繁体   English   中英

MVVM绑定视图到可更改的模型

[英]MVVM binding view to a changeable model

可以说我有一个ListBox与多个模型对象,让我们把它叫做person与像正常值nameagefamiliyName和对象的列表professions任意值。

我想现在创建一个Inspector控件,它显示所选person对象的值,但我的任务是。

Inspector视图模型是否应具有自己的属性(如SelectedPersonNameSelectedPersonAge等..)以将视图绑定到,并在列表框中的选定项更改时更新所有属性? 或者我应该通过在检查器视图模型中引用列表框中所选项目的引用来实现它,最后使用{Binding SelectedPerson.name} {Binding SelectedPerson.age}这里的最佳做法是什么? 有第三种方式吗?

第二种方式。 只要您在所选人员更改时通知,并且当该人员的属性发生更改时,它们都将正确绑定。 而且您不需要创建一堆新的viewmodel属性。

你可以为每个模型使用一个viewModel,并在它们的构造函数中初始化它们,如下所示:

public class PersonVm : DependencyObject
{
    public PersonVm(Model.Person model)
    {
        _model = model;
        Name = model.Name;
        Age = model.Age;
        foreach (var professionModel in model.Professions)
        {
            Professions.Add(new ProfessionVm(professionModel));
        }
    }
    Model.Person _model;
    public int Id { get { return _model.Id; } }
    //Name Dependency Property
    public string Name
    {
        get { return (string)GetValue(NameProperty); }
        set { SetValue(NameProperty, value); }
    }
    public static readonly DependencyProperty NameProperty =
        DependencyProperty.Register("Name", typeof(string), typeof(PersonVm), new UIPropertyMetadata(null));
    //Age Dependency Property
    public int Age
    {
        get { return (int)GetValue(AgeProperty); }
        set { SetValue(AgeProperty, value); }
    }
    public static readonly DependencyProperty AgeProperty =
        DependencyProperty.Register("Age", typeof(int), typeof(PersonVm), new UIPropertyMetadata(0));

    //Professions Observable Collection
    private ObservableCollection<ProfessionVm> _professions = new ObservableCollection<ProfessionVm>();
    public ObservableCollection<ProfessionVm> Professions { get { return _professions; } }
}

这是整个页面或窗口的viewModel,你需要在页面或窗口的构造函数中创建它的一个实例,并在InitializeComponent()之后将DataContext设置为它

public class MainViewModel : DependencyObject
{
    public MainViewModel(IEnumerable<Model.Person> models)
    {
        foreach (var personModel in models)
        {
            People.Add(new PersonVm(personModel));
        }
    }
    //People Observable Collection
    private ObservableCollection<PersonVm> _people = new ObservableCollection<PersonVm>();
    public ObservableCollection<PersonVm> People { get { return _people; } }

    //SelectedPerson Dependency Property
    public PersonVm SelectedPerson
    {
        get { return (PersonVm)GetValue(SelectedPersonProperty); }
        set { SetValue(SelectedPersonProperty, value); }
    }
    public static readonly DependencyProperty SelectedPersonProperty =
        DependencyProperty.Register("SelectedPerson", typeof(PersonVm), typeof(MainViewModel), new UIPropertyMetadata(null));
}

通过这种方式,您可以非常轻松地绑定:

<DockPanel>
    <ListBox 
        DockPanel.Dock="Left"
        ItemsSource="{Binding People}"
        SelectedItem="{Binding SelectedPerson}"
        DisplayMemberPath="Name"/>
    <StackPanel DataContext="{Binding SelectedPerson}">
        <TextBlock Text="{Binding Name}"/>
        <TextBlock Text="{Binding Age}"/>
        <ListBox ItemsSource="{Binding Professions}"
                 DisplayMemberPath="Whatever"/>
    </StackPanel>
</DockPanel>

这种方法的好处是易于绑定。 此外,模型的更新按以下方式完成:

    //Name Dependency Property
    public string Name
    {
        get { return (string)GetValue(NameProperty); }
        set { SetValue(NameProperty, value); }
    }
    public static readonly DependencyProperty NameProperty =
        DependencyProperty.Register("Name", typeof(string), typeof(PersonVm),
        new UIPropertyMetadata(null, (d, e) =>
        {
            var vm = (PersonVm)d;
            var val = (string)e.NewValue;
            vm._model.Name = val;
        }));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM