2016-11-18 74 views
0

不起作用在我們Xamarin的應用程序,我們有一個ListView,顯示用戶選擇,他們將被帶到該調查的詳情頁的調查Surveys.If的列表。爲此,我們在SelectedItem屬性上使用TwoWay綁定,並將控制器添加到控制器中的SelectedItem屬性中。Xamarin的ListView雙向綁定在iOS

Xaml-

<ListView x:Name= "surveyList" ItemsSource= "{Binding Surveys}" SelectedItem= "{Binding SelectedSurvey, Mode=TwoWay}" BackgroundColor= "White" HorizontalOptions= "Fill" SeparatorColor= "Gray" RowHeight= "50" > 

C# -

private SurveyListItem _selectedSurvey; 
public SurveyListItem SelectedSurvey 
{ 
    get { return _selectedSurvey; } 
    set 
    { 
     _selectedSurvey = value; 
     if (_selectedSurvey == null) 
     { 
      NotifyPropertyChanged(); 
      return; 
     } 
     OnSurveySelected(_selectedSurvey); 
     _selectedSurvey = null; 
     NotifyPropertyChanged(); 
    } 
} 

這工作找到AndroidiOS不起作用。點擊列表中的項目不會設置_selectedSurvey或致電設置者SelectedSurvey

我可以做一個快速修復,並將其改爲某種點擊手勢,但我們在需要多選的應用程序的其他地方使用ListView,並且將所有這些改爲點擊手勢將是一種痛苦。

任何想法,爲什麼這會爲Android工作,但不是iOS

編輯 -

完全Xaml-

<?xml version = "1.0" encoding= "utf-8" ?> 

< TabbedPage xmlns = "http://xamarin.com/schemas/2014/forms" 

      xmlns:x= "http://schemas.microsoft.com/winfx/2009/xaml" 

       x:Class= "MyApp.View.ModuleContentPage" 

      xmlns:vm= "clr-namespace:MyApp.ViewModel;assembly=MyApp" 

      xmlns:local= "clr-namespace:MyApp.View;assembly=MyApp" 

      Title= "Module Content Render" > 

    <TabbedPage.Children> 

    < ContentPage Title= "Summary" IsEnabled= "False" > 

     <ContentPage.Content> 

     < StackLayout Padding= "20, 20, 20, 0" > 

      < Label Text= "To Do: Render Module Content Here." ></ Label > 

     </ StackLayout > 

     </ ContentPage.Content > 

    </ ContentPage > 

    < ContentPage Title= "Related" > 

     <ContentPage.Content> 

     < StackLayout Padding= "20, 20, 20, 0" > 

      < Label Text= "To Do: Render Related Content Here." ></ Label > 

     </ StackLayout > 

     </ ContentPage.Content > 

    </ ContentPage > 

    < ContentPage Title= "Surveys" IsEnabled= "False" > 

     <ContentPage.Content> 

     < StackLayout Padding= "20" > 

      < ListView x:Name= "surveyList" ItemsSource= "{Binding Surveys}" SelectedItem= "{Binding SelectedSurvey, Mode=TwoWay}" BackgroundColor= "White" HorizontalOptions= "Fill" SeparatorColor= "Gray" RowHeight= "50" > 

      <ListView.Header> 

       < StackLayout Padding= "0, 0, 0, 10" VerticalOptions= "Center" > 

        < Label Text= "Surveys" FontSize= "20" TextColor= "Gray" LineBreakMode= "NoWrap" /> 

       </ StackLayout > 

      </ ListView.Header > 

      <ListView.ItemTemplate> 

       <DataTemplate> 

       <ViewCell> 

        <ViewCell.View> 

        < StackLayout VerticalOptions= "Center" > 

         < Grid ColumnSpacing= "20" > 

         <Grid.RowDefinitions> 

          < RowDefinition Height= "*" /> 

         </ Grid.RowDefinitions > 

         <Grid.ColumnDefinitions> 

          < ColumnDefinition Width= "*" /> 

          < ColumnDefinition Width= "50" /> 

         </ Grid.ColumnDefinitions > 

         < Label Text= "{Binding HydratedSurvey.Name}" FontSize= "12" TextColor= "Black" FontAttributes= "Bold" Grid.Row= "0" Grid.Column= "0" /> 

         < Label Text= "{Binding SurveyInstanceCount}" FontSize= "12" TextColor= "Green" FontAttributes= "Bold" Grid.Row= "0" Grid.Column= "1" /> 

         </ Grid > 

        </ StackLayout > 

        </ ViewCell.View > 

       </ ViewCell > 

       </ DataTemplate > 

      </ ListView.ItemTemplate > 

      </ ListView > 

     </ StackLayout > 

     </ ContentPage.Content > 

    </ ContentPage > 

    </ TabbedPage.Children > 

</ TabbedPage > 

代碼Behind-

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

using Xamarin.Forms; 

namespace MyApp.View 
{ 
    public partial class ModuleContentPage : TabbedPage 
    { 
     private Page PreviousPage { get; set; } 

     public ModuleContentPage() 
     { 
      InitializeComponent(); 

      // TODO hard coded to disabled the first two tabs and select Surveys. Remove when other tabs are finished 
      DisableTab(Children[0]); 
      DisableTab(Children[1]); 

      //Children[0].IsEnabled = false; 
      //Children[1].IsEnabled = false; 
      //PreviousPage = Children[2]; 
      //CurrentPage = PreviousPage; 
      CurrentPage = Children[2]; 

      CurrentPageChanged += ModuleContentPage_CurrentPageChanged; 
      PagesChanged += ModuleContentPage_PagesChanged; 
     } 

     private void DisableTab(Page page) 
     { 
      page.IsEnabled = false; 
      //page.Unfocus(); 
      page.Opacity = 50.0; 
     } 

     private void ModuleContentPage_PagesChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) 
     { 
      CurrentPage = Children[2]; 
     } 

     private void ModuleContentPage_CurrentPageChanged(object sender, EventArgs e) 
     { 
      CurrentPage = Children[2]; 
     } 
    } 
} 

**視圖模型 - **

using Newtonsoft.Json; 
using MyApp.DataModel.TransferObjects; 
using MyApp.DataAccess.UoW; 
using MyApp.Services; 
using MyApp.SQLiteAccess.Repository; 
using MyApp.SQLiteAccess.Tables; 
using MyApp.ViewModel; 
using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Input; 
using Xamarin.Forms; 

namespace MyApp.ViewModel 
{ 
    public class SurveyListItem : ViewModelBase 
    { 
     public SurveyDTO HydratedSurvey { get; set; } 
     private int _surveyInstanceCount; 
     public int SurveyInstanceCount { get { return _surveyInstanceCount; } set { _surveyInstanceCount = value; NotifyPropertyChanged(); } } 
    } 

    public class ModuleContentPageViewModel : ViewModelBase 
    { 
     private ModuleHydratedDTO _module; 
     public ModuleHydratedDTO Module { get { return _module; } set { _module = value; NotifyPropertyChanged(); } } 

     private ModuleContentHydratedDTO _moduleContent; 
     public ModuleContentHydratedDTO ModuleContent { get { return _moduleContent; } set { _moduleContent = value; NotifyPropertyChanged(); } } 

     SqlSurveyInstanceRepository _sqlSurveyInstanceRepository; 
     SqlSurveyInstanceRepository SqlSurveyInstanceRepository { get { return _sqlSurveyInstanceRepository ?? (_sqlSurveyInstanceRepository = new SqlSurveyInstanceRepository()); } } 

     private ObservableCollection<SurveyListItem> _surveys; 
     public ObservableCollection<SurveyListItem> Surveys { get { return _surveys; } set { _surveys = value; NotifyPropertyChanged(); } } 

     public ModuleContentPageViewModel(ModuleHydratedDTO module, ModuleContentHydratedDTO moduleContent) : base() 
     { 
      _module = module; 
      _moduleContent = moduleContent; 
      _surveys = GetSurveys(); 

      MessagingCenter.Subscribe<Stores.SurveyStore, SurveyDTO>(this, "UpdateSurveyInstanceCount", (sender, hydratedSurvey) => 
      { 
       SurveyListItem survey = _surveys.FirstOrDefault(s => s.HydratedSurvey.SurveyId == hydratedSurvey.SurveyId); 
       if (survey != null) 
       { 
        survey.SurveyInstanceCount = UoW.SurveyInstances.GetCountForSurveyIdAsync(hydratedSurvey.MasterSurveyId ?? hydratedSurvey.SurveyId, ModuleContent.ModuleContentId).Result; 
        NotifyPropertyChanged(); 
       } 
      }); 
     } 

     private ObservableCollection<SurveyListItem> GetSurveys() 
     { 
      ObservableCollection<SurveyListItem> surveyList = new ObservableCollection<SurveyListItem>(); 
      List<SurveyDTO> surveys = UoW.Surveys.GetHydratedSurveysForUser(_module.Module.ModuleId); 

      if (surveys.Count > 0) 
      { 
       foreach (var survey in surveys) 
       { 
        SurveyListItem item = new SurveyListItem(); 
        item.HydratedSurvey = survey; 
        item.SurveyInstanceCount = UoW.SurveyInstances.GetCountForSurveyIdAsync(survey.MasterSurveyId.HasValue ? survey.MasterSurveyId.Value : survey.SurveyId, ModuleContent.ModuleContentId).Result; 
        surveyList.Add(item); 
       } 
      } 
      return surveyList; 
     } 

     private SurveyListItem _selectedSurvey; 
     public SurveyListItem SelectedSurvey 
     { 
      get { return _selectedSurvey; } 
      set 
      { 
       _selectedSurvey = value; 
       if (_selectedSurvey == null) 
       { 
        NotifyPropertyChanged(); 
        return; 
       } 
       OnSurveySelected(_selectedSurvey); 
       _selectedSurvey = null; 
       NotifyPropertyChanged(); 
      } 
     } 

     private void OnSurveySelected(SurveyListItem selectedSurvey) 
     { 
      NavigationService.PushAsync(new SurveyInstanceListVM(selectedSurvey.HydratedSurvey, _moduleContent.ModuleContentId), selectedSurvey.HydratedSurvey.Name); 
     } 
    } 
} 

希望幫助

編輯編輯 -

這裏是frankenstiened視圖模型/ viewmodelbase組合。

using MyApp.DataModel.TransferObjects; 
using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.Runtime.CompilerServices; 
using MyApp.ViewModelFramework.Spooling; 

namespace MyApp.ViewModel 
{ 
    public class SurveyListItem 
    { 
     public string Name { get { return "foo"; } set { var x = value; } } 
     private int _surveyInstanceCount; 
     public int SurveyInstanceCount { get { return _surveyInstanceCount; } set { _surveyInstanceCount = value; } } 
    } 

    public class ModuleContentPageViewModel 
    { 
     private ObservableCollection<SurveyListItem> _surveys; 
     public ObservableCollection<SurveyListItem> Surveys { get { return _surveys; } set { _surveys = value; NotifyPropertyChanged(); } } 


     public ModuleContentPageViewModel(ModuleHydratedDTO module, ModuleContentHydratedDTO moduleContent) : base() 
     { 
      _surveys = GetSurveys(); 
     } 

     private ObservableCollection<SurveyListItem> GetSurveys() 
     { 
      ObservableCollection<SurveyListItem> surveyList = new ObservableCollection<SurveyListItem>(); 
      surveyList.Add(new SurveyListItem()); 
      return surveyList; 
     } 

     private SurveyListItem _selectedSurvey; 
     public SurveyListItem SelectedSurvey 
     { 
      get { return _selectedSurvey; } 
      set 
      { 
       _selectedSurvey = value; 
       if (_selectedSurvey == null) 
       { 
        NotifyPropertyChanged(); 
        return; 
       } 
       _selectedSurvey = null; 
       NotifyPropertyChanged(); 
      } 
     } 

     public void NotifyPropertyChanged([CallerMemberName] string propertyName = "") 
     { 
      InvokeNotifyPropertyChanged(propertyName); 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 

     public NotifyPropertyChangedSpooler NotificationSpooler = new NotifyPropertyChangedSpooler(); 

     private NotificationPropertyChangedStateEnum _notificationPropertyChangedState = NotificationPropertyChangedStateEnum.Active; 

     // Gets and sets change notification spooling and blocking features. 
     public NotificationPropertyChangedStateEnum NotificationPropertyChangedState 
     { 
      get { return _notificationPropertyChangedState; } 
      set 
      { 
       _notificationPropertyChangedState = value; 
       if (_notificationPropertyChangedState == NotificationPropertyChangedStateEnum.Active && !NotificationSpooler.IsEmpty) 
       { 
        NotificationSpooler.Unwind(); 
       } 
       NotifyPropertyChanged(); 

      } 
     } 


     void InvokeNotifyPropertyChanged(string propertyName) 
     { 
      switch (NotificationPropertyChangedState) 
      { 
       case NotificationPropertyChangedStateEnum.Active: 
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
        break; 
       case NotificationPropertyChangedStateEnum.Spooling: 
        NotificationSpooler.Enqueue(this, propertyName); 
        break; 
       case NotificationPropertyChangedStateEnum.Inactive: 
        break; 
      } 
     } 
    } 

    public enum NotificationPropertyChangedStateEnum 
    { 
     Inactive = 0, 
     Active = 1, 
     Spooling = 3 
    } 
} 
+0

你如何定義你的列表?它只是一個列表或ObservableCollection?更多的代碼和xaml將有所幫助。理想情況下,如果您可以將完整的代碼發佈到包含模型的頁面和代碼後面,我們可能會幫助更快 –

+0

這是一個ObservableCollection。我更新了頁面xaml,後面的代碼,並查看模型 –

+0

即將嘗試......您是在設備上還是在模擬器上測試?什麼是iOS版本? –

回答

1

經過一番調查發現,該網頁在xaml中被禁用,並且從未在xaml和代碼後面啓用過。由於某種原因,它在Android中不是問題(這是一種錯誤,應該調查更多爲什麼)。

+0

謝謝尤里,因爲花了這麼多時間來研究這個並幫助我們解決這個問題! - 如果我能給這個傢伙超過1+我會:) –

+0

@MicahWilliamson我的榮幸 –