MVVM绑定了很多属性

时间:2017-06-08 20:45:19

标签: c# wpf xaml mvvm binding

是否有一种简单的方式来绑定许多属性?

因此,如果您有一个包含属性的Person类:姓氏,名字,生日,性别,标题,......

现在我为ViewModel上的每个属性执行此操作:

 public string _LastName;
 public string LastName
 {
    get { return _LastName; }
    set { _LastName = value;
          RaisePropertyChanged("LastName"); }
 } 

在XAML页面上这个绑定:

 <TextBlock Text="{Binding FirstName}" />

现在图像如果Person对象有20个属性.. 所以我的问题是我可以用一种简单的方式做到这一点吗?

4 个答案:

答案 0 :(得分:2)

如果您确实打算在运行时动态更新属性,则只需要从数据绑定属性的setter中引发PropertyChanged事件。否则,您可以使用自动实现的属性,而无需任何自定义逻辑:

public FirstName { get; set; }

还有一个名为Fody的NuGet包可以自动将简单的公共属性转换为完整的INotifyPropertyChanged实现:https://github.com/Fody/PropertyChanged

答案 1 :(得分:0)

如果您使用第三方MVVM框架,它也可能有一个代码片段来使用INotifyPropertyChanged创建属性。

如果您使用Catel,可以在此处下载模板和代码: http://catelproject.com/downloads/general-files/

这里是Caliburn.Micro的实施: https://github.com/winterdouglas/propc

答案 2 :(得分:0)

最简单的解决方案是使用免费POCO mechanism提供的DevExpress MVVM Framework。 POCO将自动实施INotifyPropertyChanged并为您的视图模型中的所有公共虚拟属性举起PropertyChanged事件。

当您使用 ViewModelSource 类创建视图模型时,会发生所有魔法。您可以在XAML中创建视图模型:

this.DataContext = ViewModelSource.Create(() => new MyViewModel());

或代码隐藏:

 android:scaleType="center"

答案 3 :(得分:0)

<强> PREMISE

在默认MVVM方案中,您的ViewModel 没有每个属性上发出通知。

典型案例:您从数据库中获取一些Person,在View上显示它们,通过TextBoxes和其他控件修改它们,然后单击“保存”将它们重新发送到数据库。您可以通过每次调用数据库时在视图上设置DataContext来执行此操作。此操作会引发对控件和每个子控件的绑定属性的第一次更新,因此ViewModel绑定属性的所有getter都会被调用一次,View get将填充ViewModel的值。在View上修改某些内容时,该绑定会对相应的ViewModel属性进行修改(即使是简单的get-set属性)。

在这种情况下,您可以使用以下内容:

public class Person
{
    public string Name { get; set; }
    public string Surname { get; set; }
    //and so on...
}

仅当View必须侦听某些属性的更改时,才需要为ViewModel的属性发出通知。例如,此功能:当{且仅Button上的Name不为空时,Person“保存”已启用。显然,Button必须能够查看Name属性何时更改,以便属性设置者必须引发PropertyChanged事件。

可能的实施:

将此作为ViewModels的基类:

protected abstract BaseViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    protected void SetAndNotifyIfChanged<T>(
        ref T field, T value, [CallerMemberName] string propertyName = null)
    {
        if (!EqualityComparer<T>.Default.Equals(field, value))
        {
            field = value;
            NotifyPropertyChanged(propertyName);
        }
    }
}

在派生类中,您可以编写每个get-set属性,如下所示:

class MyViewModel : BaseViewModel
{
    public string MyProp
    {
        get { return _MyProp; }
        set { SetAndNotifyIfChanged(ref _MyProp, value); }
    }
    private string _MyProp;
}

自动推断类型T和参数propertyName

这是您可以编写的最短代码,与普通的完整属性没有太大区别:

    public string NormalProp
    {
        get { return _ NormalProp; }
        set { _NormalProp = value; }
    }
    private string _MyProp;

如果您不想每次都写下所有代码,请使用code snippet