不起作用在我們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();
}
}
這工作找到Android
但iOS
不起作用。點擊列表中的項目不會設置_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
}
}
你如何定義你的列表?它只是一個列表或ObservableCollection?更多的代碼和xaml將有所幫助。理想情況下,如果您可以將完整的代碼發佈到包含模型的頁面和代碼後面,我們可能會幫助更快 –
這是一個ObservableCollection。我更新了頁面xaml,後面的代碼,並查看模型 –
即將嘗試......您是在設備上還是在模擬器上測試?什麼是iOS版本? –