gpt4 book ai didi

c# - MVVM 创建 ViewModel

转载 作者:行者123 更新时间:2023-11-30 22:11:55 25 4
gpt4 key购买 nike

有人可以向我解释如何为 MVVM 模式创建 ViewModel。我试图理解这里的教程:http://msdn.microsoft.com/en-us/magazine/dd419663.aspx ,但我无法理解代码中到底发生了什么。

假设我们要创建一个基本应用程序,用于从本地数据库获取人员和向本地数据库添加人员,并在 View 中显示他们。 ViewModel 应该是什么样子以及如何为其创建 RelayCommand。首先,为什么我们要将变量设置两次:一次是私下的,然后是一次公开的。

编辑:感谢到目前为止的帮助。我还有一件事不知道要做 - 如何将 View 绑定(bind)到 ViewModel,反之亦然

这是模型:

public class Student : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;

private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}

private string name;
private string surname;
private string age;

public string Name
{
get
{
return name;
}
set
{
name = value;
OnPropertyChanged("Name");
}
}

public string Surname
{
get
{
return surname;
}
set
{
surname = value;
OnPropertyChanged("Surname");
}
}

public string Age
{
get
{
return age;
}
set
{
age = value;
OnPropertyChanged("Age");
}
}
}

这是 ViewModel:

public class MainViewModel : ViewModelBase
{
ObservableCollection<Student> studentList;
Student selectedPerson;

public MainViewModel()
{
//populate some sample data
studentList = new ObservableCollection<Student>()
{
new Student(){Name="John", Surname="Smith", Age="28"},
new Student(){Name="Barbara", Surname="Anderson", Age="23"}
};
}

public ObservableCollection<Student> StudentList
{
get { return studentList; }
}

public Student SelectedPerson
{
get { return selectedPerson; }
set
{
selectedPerson = value;
RaisePropertyChanged("SelectedPerson");
}
}

private RelayCommand _addStudentCommand;
public ICommand AddStudentCommand
{
get
{
return _addStudentCommand
?? (_addStudentCommand = new RelayCommand(() =>
{
Student student = new Student();
studentList.Add(student);
}));
}
}
}

我找到了一种使用 Csharp 中的 View 代码将 ViewModel 绑定(bind)到 View 的方法,但是如何将 View 绑定(bind)到 ViewModel 的问题仍然在我的脑海中。更具体地说,如何使用用户在 View 中输入的值创建新学生。

这是 View 的 XAML 代码

<Window x:Class="MVVMLight.View.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
SizeToContent="WidthAndHeight">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="2*"/>
<RowDefinition Height="2*"/>
<RowDefinition Height="2*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>

<TextBlock x:Name="NameTextBlock"
Text="Name"
Style="{StaticResource TextBlockTextStyle}"/>
<TextBlock x:Name="SurnameTextBlock"
Grid.Row="1"
Text="Surname"
Style="{StaticResource TextBlockTextStyle}"/>
<TextBlock x:Name="AgeTextBlock"
Grid.Row="2"
Text="Age"
Style="{StaticResource TextBlockTextStyle}"/>
<TextBox x:Name="NameTextBox"
Grid.Column="1"
Style="{StaticResource TextBoxTextStyle}"/>
<TextBox x:Name="SurnameTextBox"
Grid.Row="1"
Grid.Column="1"
Style="{StaticResource TextBoxTextStyle}"/>
<TextBox x:Name="AgeTextBox"
Grid.Row="2"
Grid.Column="1"
Style="{StaticResource TextBoxTextStyle}"/>
<ListBox x:Name="StudentListBox"
Grid.ColumnSpan="2"
Grid.Row="4"
Style="{StaticResource ListBoxStyle}"
ItemsSource="{Binding StudentList}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}"
Style="{StaticResource TextBlockTextStyle}"/>
<TextBlock Text="{Binding Surname}"
Grid.Column="1"
Style="{StaticResource TextBlockTextStyle}"/>
<TextBlock Text="{Binding Age}"
Grid.Column="2"
Style="{StaticResource TextBlockTextStyle}"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button x:Name="AddButton"
Grid.Row="7"
Grid.ColumnSpan="2"
HorizontalAlignment="Center"
Content="Add"
Margin="7,7,7,7"
Command="{Binding AddStudentCommand}"/>
</Grid>

这是 View 的 Csharp 代码

 public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new MainViewModel();
}
}

我对 View 和 ViewModel 之间的绑定(bind)有一些疑问:使用这种类型的绑定(bind)有哪些优点和缺点?如果我要使用数据库,最好的绑定(bind)方式是什么?

  1. ViewModel 和 Model 应该是这样吗
  2. 如何创建 RelayCommand 以将学生添加到 ObservableCollection
  3. 为什么我们要先私下设置,然后再公开设置[已回答]
  4. 如何将 View 绑定(bind)到 ViewModel,反之亦然

最佳答案

在您的属性 setter 中,您应该检查新值是否等于旧值,如果是,您应该返回而不触发 PropertyChanged 事件。

关于您的问题:

  1. 是的,这看起来不错。
  2. 有几种方法可以设置您的中继命令。我更喜欢

    private RelayCommand<Student> _addStudentCommand;
    public ICommand AddStudentCommand
    {
    get
    {
    return _addStudentCommand
    ?? (_addStudentCommand = new RelayCommand<Student>((student) =>
    {
    studentList.Add(student);
    }));
    }
    }

不传入学生对象的另一种方式

private RelayCommand _addStudentCommand;
public ICommand AddStudentCommand
{
get
{
return _addStudentCommand
?? (_addStudentCommand = new RelayCommand(() =>
{
Student student = new Student();
studentList.Add(student);
}));
}
}
  1. 这就是属性在 .net 中的工作方式,您可以使用自动属性,但由于您需要在 setter 中触发更改通知,因此您必须声明该属性将起作用的字段。

此外,由于看起来您正在使用 mvvm light,因此您应该尝试代码片段。它们使属性非常容易创建。输入 mvvvminpc 然后点击 Tab 键两次。然后填写突出显示的部分并点击选项卡直到完成。

您可以通过多种方式将 View 绑定(bind)到 View 模型。我知道这是一个反模式,但您可以使用定位器。基本思想是将 View 模型设置为 View 数据上下文。

public class Locator
{
public Viewmodel1 Viewmodel1
{
return new Viewmodel1();
}
}

然后在你的 app.xaml 中添加这个类

<Application.Resources>
<Locator x:key="VMLocator" />
</Application.Resources>

然后在你的xaml View 中

<Page  DataContext="{Binding Source="{StaticResource VMLocator}" Path=ViewModel1}">

</Page>

关于c# - MVVM 创建 ViewModel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19984438/

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