我有一个视图,其中包含一组来自Web服务的图像 我在这个课程列表中收到它们:
public class ImageModel
{
public int Id { get; set; }
public string Name { get; set; }
public string imageUrl { get; set; }
}
在每张图片下我都会显示一个向上投票按钮,所以我在上面的模型中添加了另一个bool属性:
public bool UpVoted { get; set; }
显示这些图片的ListView
绑定到ObservableCollection<ImageModel >
,我想通过将UpVoted
的值转换为相应图标的转换器更改投票图标,用户单击投票图标:执行此方法的命令:
private void OnVoting(ImageModel image)
{
Images.Single(x => x.id == image.id).UpVoted = !image.UpVoted;
}
问题是UI没有更新,为了确保我理解了问题,我将模型转换为View模型,并对UpVoted
属性进行了必要的更改(我使用的是MVVM灯库)
bool upVoted;
public bool UpVoted
{
get { return upVoted; }
set
{
Set(ref upVoted, value);
}
}
它现在有效,
所以我需要将UpVoted
绑定到UI,因此无论何时更改
答案 0 :(得分:2)
第一 您的模型类必须继承自MvxNotifyPropertyChanged
public class ImageModel : MvxNotifyPropertyChanged
{
public int Id { get; set; }
public string Name { get; set; }
private bool upVoted ;
public bool UpVoted
{
get { return upVoted ; }
set { upVoted = value; RaisePropertyChanged(() => UpVoted ); }
}
}
然后用MvxValueConverter
准备好了
答案 1 :(得分:1)
穆斯塔法的回答提到了一个专门针对MvvmCross图书馆的课程
另一种选择是where
。
如果您希望编写自己的MVVM(或了解MVVM的工作原理), 一般模式是实现INotifyPropertyChanged:Implement Property Change Notification,I discuss here。
实现INotifyPropertyChanged的一种简便方法是创建一个执行该实现的基类,然后从该基类继承。您可以使用该示例中的代码作为基类。或者使用稍微不同的实现,避免必须手动将属性名称作为字符串传递:
TinyMvvm
同样,上述代码的替代方法是使用现有的MVVM库。
对于另一种选择,不需要在所有属性设置器中编写“SetProperty(..)”或“OnPropertyChanged(..)”,谷歌有关使用{{3>的信息}}。那你就不需要上面的代码了;你的班级只会继承using System.ComponentModel;
using System.Runtime.CompilerServices;
// Use this as base class for all your "view model" classes.
// And possibly for your (domain) model classes.
// E.g.: "public class MyLoginViewModel : HasNotifyPropertyChanged".
// OR "public class MyLoginModel : HasNotifyPropertyChanged".
// Give it whatever name you want, for ViewModels I suggest "ViewModelBase".
public class HasNotifyPropertyChanged : INotifyPropertyChanged
{
// --- This is pattern to use to implement each property. ---
// This works for any property type: int, Color, etc.
// What's different from a standard c# property, is the "SetProperty" call.
// You will often write an IValueConverter (elsewhere) to use in XAML to convert from string to your property type,
// or from your property type to a type needed in your UI.
// Comment out this example property if you don't need it.
/// <summary>
/// Set to "true" at end of your initialization.
/// Then can use Property Trigger on Ready value=true in XAML to do something when your instance is ready for use.
/// For example, load something from web, then trigger to update UI.
/// </summary>
private bool _ready;
public bool Ready
{
get => _ready;
set => SetProperty(ref _ready, value);
}
public event PropertyChangedEventHandler PropertyChanged;
protected void SetProperty<T>(ref T property, T value, [CallerMemberName] string propertyName = null)
{
if (property == null || !property.Equals(value))
{
property = value;
RaisePropertyChanged(propertyName);
}
}
protected void RaisePropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
。 (在app启动时,你调用一个方法,将所需的逻辑“注入”所有INotifyPropertyChanged类的所有属性。)
确认:上面示例中的代码模式基于其中一个开源库。它可能来自TinyMvvm。
答案 2 :(得分:0)
您没有说明您正在使用哪种容器,但并非所有控件都设置为默认支持双向通知。所以你可能需要添加一个
Mode=TwoWay
从后端获取数据已更改的通知。或者,正如Mustafa先前的回答所示,您可能需要验证您的班级是否正在使用mvvm灯实施InotifyPropertyChanged事件。