WPF经典编程模式-MVVM示例讲解(转载)
时间: 2023-10-08 22:07:39 浏览: 89
MVVM(Model-View-ViewModel)是一种经典的WPF编程模式,它将应用程序分为三个部分:模型(Model)、视图(View)和视图模型(ViewModel)。其中,模型表示业务数据和规则,视图显示用户界面,视图模型则充当模型和视图之间的中介,负责协调数据和业务逻辑与视图的交互。
下面我将通过一个简单的示例来讲解MVVM模式在WPF中的应用。
首先,我们需要创建一个WPF应用程序,并添加一个MainWindow.xaml文件作为主窗口。
然后,我们定义一个模型类,表示一个人员信息,包括姓名和年龄:
```csharp
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
```
接着,我们创建一个视图模型类,负责管理人员信息的增删改查操作,并与视图进行交互。在这个示例中,我们只实现了添加和删除功能:
```csharp
public class ViewModel : INotifyPropertyChanged
{
private ObservableCollection<Person> _persons;
public ObservableCollection<Person> Persons
{
get { return _persons; }
set
{
_persons = value;
OnPropertyChanged(nameof(Persons));
}
}
private string _name;
public string Name
{
get { return _name; }
set
{
_name = value;
OnPropertyChanged(nameof(Name));
}
}
private int _age;
public int Age
{
get { return _age; }
set
{
_age = value;
OnPropertyChanged(nameof(Age));
}
}
public RelayCommand AddCommand { get; set; }
public RelayCommand<Person> RemoveCommand { get; set; }
public ViewModel()
{
Persons = new ObservableCollection<Person>();
AddCommand = new RelayCommand(AddPerson);
RemoveCommand = new RelayCommand<Person>(RemovePerson);
}
private void AddPerson()
{
Persons.Add(new Person { Name = Name, Age = Age });
Name = "";
Age = 0;
}
private void RemovePerson(Person person)
{
Persons.Remove(person);
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public class RelayCommand : ICommand
{
private readonly Action _execute;
private readonly Func<bool> _canExecute;
public RelayCommand(Action execute, Func<bool> canExecute = null)
{
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return _canExecute == null || _canExecute();
}
public void Execute(object parameter)
{
_execute();
}
public event EventHandler CanExecuteChanged;
public void RaiseCanExecuteChanged()
{
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
}
public class RelayCommand<T> : ICommand
{
private readonly Action<T> _execute;
private readonly Func<T, bool> _canExecute;
public RelayCommand(Action<T> execute, Func<T, bool> canExecute = null)
{
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return _canExecute == null || _canExecute((T)parameter);
}
public void Execute(object parameter)
{
_execute((T)parameter);
}
public event EventHandler CanExecuteChanged;
public void RaiseCanExecuteChanged()
{
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
}
```
注意,在这个视图模型类中,我们实现了INotifyPropertyChanged接口,以便在属性值发生变化时通知视图进行更新。此外,我们还定义了两个命令AddCommand和RemoveCommand,分别用于添加和删除人员信息,这里使用了一个简单的ICommand实现RelayCommand。
最后,我们在MainWindow.xaml中定义视图,并将其绑定到视图模型中的属性和命令:
```xml
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApp1"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:ViewModel/>
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal" Margin="10">
<Label Content="Name:" VerticalAlignment="Center"/>
<TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}" Width="100" Margin="5"/>
<Label Content="Age:" VerticalAlignment="Center" Margin="10,0,0,0"/>
<TextBox Text="{Binding Age, UpdateSourceTrigger=PropertyChanged}" Width="50" Margin="5"/>
<Button Content="Add" Command="{Binding AddCommand}" Margin="10,0"/>
</StackPanel>
<ListBox Grid.Row="1" ItemsSource="{Binding Persons}" Margin="10"
SelectedItem="{Binding SelectedPerson}" SelectionMode="Single">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" Margin="5"/>
<TextBlock Text="{Binding Age}" Margin="5"/>
<Button Content="Remove" Command="{Binding DataContext.RemoveCommand, RelativeSource={RelativeSource AncestorType=ListBox}}"
CommandParameter="{Binding}" Margin="10,0"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Window>
```
在这个视图中,我们使用了DataTemplate来定义ListBox的项模板,其中包含一个文本块和一个删除按钮。注意,在删除按钮的命令绑定中,我们使用了RelativeSource来指定数据上下文为ListBox的视图模型,并将选中的人员信息作为参数传递给RemoveCommand。
到此为止,一个简单的MVVM示例就完成了。通过这个示例,我们可以看到MVVM模式在WPF中的应用,它能够有效地将业务逻辑和用户界面进行分离,使得应用程序更加清晰、易于维护。
阅读全文