C# 尽管已成功并正确引发PropertyChanged事件,但绑定未更新
我有一个名为SubjectsPage的页面,其绑定上下文设置为SubjectsPageViewModel。SubjectsPage中有一个SfListView控件(Syncfusion),其中其ItemsSource已设置为Subjects ObservableCollection属性,该属性使用INotifyPropertyChanged模式,如下所示:C# 尽管已成功并正确引发PropertyChanged事件,但绑定未更新,c#,xaml,xamarin.forms,xamarin.android,xamarin.ios,C#,Xaml,Xamarin.forms,Xamarin.android,Xamarin.ios,我有一个名为SubjectsPage的页面,其绑定上下文设置为SubjectsPageViewModel。SubjectsPage中有一个SfListView控件(Syncfusion),其中其ItemsSource已设置为Subjects ObservableCollection属性,该属性使用INotifyPropertyChanged模式,如下所示: private ObservableCollection<Subject> _subjects;
private ObservableCollection<Subject> _subjects;
public ObservableCollection<Subject> Subjects
{
get => _subjects;
set => SetProperty(ref _subjects, value, Subjects);
}
如上所述,我的BindingContext是在OnAppearing中设置的,因为我需要使用异步方法初始化视图模型属性设置为的一些支持属性。在这里设置是否会造成某种断开
SubjectsPage继承自BasePage,后者继承自ContentPage,因为我的所有页面都需要一个附加属性。这不会影响任何内容,因为导航到的下一个页面也继承了此BasePage
主题页面
protected async override void OnAppearing()
{
base.OnAppearing();
if (Initialised is false)
await SetContext();
IncrementTest();
}
async Task SetContext()
{
BindingContext = await SubjectsPageViewModel.InitialiseAsync();
Initialised = true;
}
<views:BasePage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:xforms="clr-namespace:Syncfusion.ListView.XForms;assembly=Syncfusion.SfListView.XForms"
xmlns:viewmodels="clr-namespace:TraceIt.ViewModels"
xmlns:models="clr-namespace:TraceIt.Models"
xmlns:views="clr-namespace:TraceIt.Views"
mc:Ignorable="d"
x:Class="TraceIt.Views.SubjectsPage"
Title="Subjects"
BackgroundColor="Black"
x:Name="Page">
//Styling and ToolbarItems
<!--<views:BasePage.BindingContext>
<viewmodels:SubjectsPageViewModel/>
</views:BasePage.BindingContext>-->
<views:BasePage.Content>
<AbsoluteLayout Style="{DynamicResource gradientAbsoluteLayout}">
<StackLayout Padding="0" AbsoluteLayout.LayoutFlags="All"
AbsoluteLayout.LayoutBounds="0, 0, 1, 1">
<Label Text="{Binding TestInt}" TextColor="White"/> // Test label (doesn't work)
<xforms:SfListView x:Name="collectionViewSubjects" AutoFitMode="Height"
ItemSpacing="{OnIdiom Tablet=20, Phone=10}"
SelectionMode="None" ItemsSource="{Binding Subjects}">
<xforms:SfListView.LayoutManager>
<xforms:GridLayout SpanCount="2"/>
</xforms:SfListView.LayoutManager>
<xforms:SfListView.ItemTemplate>
<DataTemplate> // Not single binding here updates after property changes
<Frame Style="{DynamicResource listItemFrame}" Padding="0">
<StackLayout Padding="10, 13, 10, 20">
<Label Text="{Binding Name}" FontAttributes="Bold"
Margin="0, 0, 0, 12"/>
<Label Text="{Binding Credits, StringFormat='0 / {0} credits'}"/>
<Label Text="{Binding StandardsCount, StringFormat='{0} standards'}" Margin="0, 0, 0, 12"/>
<Button Text="View Info" CornerRadius="20"
TextColor="Black" FontAttributes="Bold"
FontSize="17" Style="{DynamicResource subjectButtonGradient}"
Clicked="buttonViewInfo_Clicked" HorizontalOptions="Center"
WidthRequest="200" HeightRequest="40"
VerticalOptions="End"/>
</StackLayout>
</Frame>
</SwipeView>
</DataTemplate>
</xforms:SfListView.ItemTemplate>
</xforms:SfListView>
</StackLayout>
</AbsoluteLayout>
</views:BasePage.Content>
</views:BasePage>
主题模型的剪贴,主题页面中的一个属性未进行可视化更新:
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public void SetProperty<T>(ref T property, T value, T publicProperty)
{
property = value;
OnPropertyChanged(nameof(publicProperty));
}
private void SetCredits()
{
Credits = 0;
foreach (var standard in Standards)
AddStandardCredits(standard);
}
void AddStandardCredits(Standard standard)
{
if (standard.FinalGrade is Standard.Grade.Excellence)
ExcellenceCredits += standard.Credits;
else if (standard.FinalGrade is Standard.Grade.Merit)
MeritCredits += standard.Credits;
Credits += standard.Credits;
}
public class Subject : BaseModel, ISubjectItem
请随意询问可能有助于您回答的任何其他信息。因此,我发现问题不是源于ViewModels,也不是源于Models,而是源于BaseViewModel(和BaseModel)。为了让事情变得更简单,我尝试使用以下语法:
public void SetProperty<T>(ref T property, T value, T publicProperty)
{
property = value;
OnPropertyChanged(nameof(publicProperty));
}
public void SetProperty(ref T property、T value、T publicProperty)
{
财产=价值;
OnPropertyChanged(公共财产的名称);
}
问题在于nameof(publicProperty
没有给出在参数中传递的属性的名称,而只是给出局部变量名“publicProperty”。因此,尽管引发了PropertyChanged
事件,但每次都以错误的名称抛出该事件,因此永远不会到达其各自属性的事件订阅者
我修改了SetProperty的用法,现在它需要一个字符串作为第三个参数传递,在这里我必须使用
nameof()
每次。主题的代码在哪里?我添加了一个片段,SetProperty方法与前面提到的相同。我不认为模型是问题所在,因为绑定到非模型相关的属性时,我的测试标签也无法更新。这在我看来还行。我不知道SF是否在进行某种默认cach使用与标准XF ListView不同的ListView进行绑定我没有更改任何缓存设置,但下一页也没有设置任何缓存设置,但绑定会正确更新。感谢您的共享,请不要忘记接受您的答案,这将帮助其他有类似问题的人。
public void SetProperty<T>(ref T property, T value, T publicProperty)
{
property = value;
OnPropertyChanged(nameof(publicProperty));
}