C# 实现INotifyPropertyChanged的属性中的更改未反映在UI中
我正在尝试实现MVVM模式,但不幸的是,它花费的时间比预期的要长 我有一个由ContactsSVM的ObservableCollection填充的ListView,添加或删除Contacts效果很好,当试图通过选择它来更改此集合中的一个项目时,问题就出现了 我在其中设置绑定的Xaml:C# 实现INotifyPropertyChanged的属性中的更改未反映在UI中,c#,xamarin,mvvm,data-binding,viewmodel,C#,Xamarin,Mvvm,Data Binding,Viewmodel,我正在尝试实现MVVM模式,但不幸的是,它花费的时间比预期的要长 我有一个由ContactsSVM的ObservableCollection填充的ListView,添加或删除Contacts效果很好,当试图通过选择它来更改此集合中的一个项目时,问题就出现了 我在其中设置绑定的Xaml: <ListView ItemsSource="{Binding ContactsToDisplay}" SelectedItem="{Binding SelectedC
<ListView ItemsSource="{Binding ContactsToDisplay}"
SelectedItem="{Binding SelectedContact, Mode=TwoWay}"
SeparatorColor="Black"
ItemSelected="OnItemSelected">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding FirstName}"
Detail="{Binding Id}">
<TextCell.ContextActions>
<MenuItem
Text="Delete"
IsDestructive="true"
Clicked="Delete_OnClicked"
CommandParameter="{Binding .}" />
</TextCell.ContextActions>
</TextCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
BaseViewModel:
public class BaseViewModel
{
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected void SetValue<T>(ref T backingField, T value, [CallerMemberName]string propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(backingField, value))
return;
backingField = value;
OnPropertyChanged(propertyName);
}
}
公共类BaseViewModel
{
公共事件属性更改事件处理程序属性更改;
[NotifyPropertyChangedInvocator]
受保护的虚拟void OnPropertyChanged([CallerMemberName]字符串propertyName=null)
{
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(propertyName));
}
受保护的void SetValue(ref T backingField,T value,[CallerMemberName]字符串propertyName=null)
{
if(EqualityComparer.Default.Equals(backingField,value))
返回;
backingField=值;
OnPropertyChanged(propertyName);
}
}
如您所见,我正在尝试更新每个选定联系人的FirstName=“Test”,更改后的联系人将被更新,但不幸的是,这些联系人没有反映在UI中,希望您能帮助我找到我做错的地方
提前谢谢 我猜
NotifyPropertyChangedInvocator
属性没有正确地通知属性更改。但我对此不确定。因为您的BaseViewModel没有实现INotifyPropertyChanged接口
下面的代码对我来说很好。这就是我在整个项目中使用它的方式
我已经在我的BaseModel
中直接派生了INotifyPropertyChanged
接口,并实现了属性更改
public class BaseModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = "")
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public class ContactVm : BaseModel
{
private string _firstName;
public int Id { get; set; }
public string FirstName
{
get { return _firstName; }
set
{
this._firstName = value;
NotifyPropertyChanged();
}
}
}
这是我回电话的内容
public void SelectContact(ContactVm contact)
{
if (contact == null)
return;
contact.FirstName = "Test";
}
唯一的区别是我也在ViewModel中实现了ObservableCollection的属性更改
public ObservableCollection<ContactVm> ContactsToDisplay
{
get { return _contactsToDisplay; }
set
{
this._contactsToDisplay = value;
NotifyPropertyChanged();
}
}
public ObservableCollection contacts可显示
{
获取{return\u contactsToDisplay;}
设置
{
这。_contactsstodisplay=值;
NotifyPropertyChanged();
}
}
请注意,在我的案例中,我没有使用您的SelectedContact绑定。可能正如你所说,约束将是一个问题
我希望它能帮助你 因为您使用了MVVM,所以当您在listview中选择item时,您可以在ViewModel中直接处理逻辑(不再需要定义ItemSelected事件)
不要忘了对您的模型和viewmodel实现INotifyPropertyChanged。您的BaseViewModel没有实现INotifyPropertyChanged接口。我刚刚测试了它,不幸的是它不起作用,可能绑定有问题吗?它对我来说很好。我所能看到的只是BaseViewModel没有实现INotifyPropertyChanged接口。除此之外,唯一的区别是我还为视图模型更改了属性通知。我还没有绑定所选联系人。可能是绑定是不需要的,因此它实际上可能会还原发生的更改。我修改过的答案对我来说很好。如果它仍然不起作用,你最好分享你的样本,这样我就可以在我这边测试它。我至少可以知道为什么我的问题被否决了吗?是的。这也是我在回答中提到的。希望你工作顺利。快乐编码…)@维克多,如果我的回答解决了你的问题,欢迎你接受。不是真的,但不管怎样。是现在吗?请检查一下是的,是的。谢谢
public class BaseModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = "")
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public class ContactVm : BaseModel
{
private string _firstName;
public int Id { get; set; }
public string FirstName
{
get { return _firstName; }
set
{
this._firstName = value;
NotifyPropertyChanged();
}
}
}
public void SelectContact(ContactVm contact)
{
if (contact == null)
return;
contact.FirstName = "Test";
}
public ObservableCollection<ContactVm> ContactsToDisplay
{
get { return _contactsToDisplay; }
set
{
this._contactsToDisplay = value;
NotifyPropertyChanged();
}
}
private ContactVm _selectedContact;
public ContactVm SelectedContact
{
set
{
if (_selectedContact!= value)
{
_selectedContact= value;
SelectedContact.FirstName="Test";
NotifyPropertyChanged("SelectedContact");
}
}
get { return _selectedContact; }
}