gpt4 book ai didi

c# - wpf 应用程序 mvvm 如何正确构建

转载 作者:太空宇宙 更新时间:2023-11-03 18:24:49 25 4
gpt4 key购买 nike

我正在尝试学习 MVVM,但遇到了一些麻烦。我是 xaml 和 c# 的新手。

我目前拥有的:

  • 一个person类,它定义了一个person对象:姓名、年龄和其他信息

  • 模型类people,拥有一个私有(private)链表(人员列表),其中还包含getremove等方法>, 添加并做一些计算

  • 一个 View 模型类,在代码背后的 xaml 和模型之间进行转换/解析/转换。

  • 代码文件 mainWindow.xaml.cs 后的 xaml,监听按钮点击等,从 viewModel 类调用方法,并进行一些简单的绑定(bind),例如 total.Content = objModelView.getTotal()

我没有使用 INotifyPropertyChanged ObservableCollection,我仍在努力思考它。虽然我的程序执行我想要的操作,但我不确定如何更好地构建它。

基本上我有两个主要问题:

  1. 我在网上看到人们在 viewmodel 中存储/启动项目列表的示例,难道我不应该将列表保留在模型中吗,那应该是存储所有数据的地方吗?
  2. 假设我想将所有项目(在模型类的列表中)显示到数据网格上。现在在我的程序中:mainWindow.xaml.cs 将检测按钮单击,然后它要求 viewModel 将其存储在模型中,如果没有错误,则代码后面的 xaml 将执行people_dataGrid.Items.Add(new person { name = newName, age = newAge, address = newAdd }); 这是不好的做法吗?不知道如何在此处使用 ObservableCollection,它能否以某种方式检测到我的模型类列表中的更改,然后删除行并将行添加到数据网格?

我已经看了一整天了,但我在这里很震惊,希望我能得到一些指导

最佳答案

模型存储数据, View 显示数据, View 模型是两者之间的桥梁。

这并不意味着 View 可以直接访问模型数据,因为您并不总是需要在模型层中显示所有数据。所以我们有一个 View 模型层,它只提供有用的信息。

当您想多次显示相同的数据但显示不同时, View 模型非常有用:您不必复制数据,只需定义两次您需要从这些数据中获取哪些信息以及如何显示它们。

您在第二个问题中所做的是在 View 中使用模型:这不是 MVVM。您要做的是将 Datagrid 的 ItemsSource DP 绑定(bind)到 PersonVM 列表,后者将从 Person 获取信息。

你的代码可以这样构造:

public class Person {
public String Name {get; set;}
public int Age {get; set;}
}

public class PersonVM {
public PersonVM(Person model) {
_model = model;
}

private readonly Person _model;
internal Person Model {get {return _model;}}

public String Name {
get { return _model.Name; }
set { _model.Name = value; }
}
public int Age {
get {return _model.Age;}
set { _model.Name = value; }
}
}

//PersonV.xaml

<StackPanel>
<TextBlock Text="{Binding Name}"/>
<TextBlock Text="{Binding Age}"/>
</StackPanel>


public class People : ObservableCollection<Person> {

}

public class PeopleVM : ObservableCollection<PersonVM> {

public PeopleVM(People model) {
_model = model;
foreach(Person p in _model) {
Add(new PersonVM(p));
}
_model.CollectionChanged += CollectionChangedHandler;
}

private void CollectionChangedHandler(Object sender, NotifyCollectionChangedEventArgs args) {
switch (notifyCollectionChangedEventArgs.Action) {
case NotifyCollectionChangedAction.Add:
foreach(People p in args.NewItems) {
if(!this.Any(pvm => pvm.Model == p)) {
this.Add(new PersonVM(p));
}
}

break;
case NotifyCollectionChangedAction.Remove:
foreach(People p in args.OldItems) {
PersonVM pvm = this.FirstOrDefault(pe => pe.Model == p);
if(pvm != null) this.Remove(pvm);
}
break;
case NotifyCollectionChangedAction.Reset:
Clear();
break;
default:
break;
}
}

private readonly People _model;
}

//PeopleV.xaml
<ItemsControl ItemsSource={Binding}>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type PersonVM}">
<PersonV/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

public class AppVM {
public AppVM() {
People p = ServiceLayer.LoadPeople(); //load people
People = new PeopleVM(p);
}

public PeopleVM People {get; set;};
}

//MainWindow.xaml
<Window ...
>
<Window.DataContext>
<local:AppVM/>
</Window.DataContext>
<PeopleV/>
</Window>

关于c# - wpf 应用程序 mvvm 如何正确构建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37202068/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com