在C#中实现MVVM(Model-View-ViewModel)架构时,可以总结以下几个关键知识点,并通过具体的代码示例来进行说明。
1. 模型 (Model)
模型包含应用程序中的数据和业务逻辑。通常与数据库交互。
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
2. 视图 (View)
视图是UI部分,包括窗口、控件以及布局等。
<Window x:Class="MVVMExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TextBox x:Name="txtName" Margin="10" Text="{Binding User.Name, UpdateSourceTrigger=PropertyChanged}" />
<TextBox x:Name="txtAge" Margin="10" HorizontalAlignment="Right" Text="{Binding User.Age, StringFormat={} {0:D2}, UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</Window>
3. 视图模型 (ViewModel)
视图模型封装了应用程序的数据逻辑和业务规则,并且负责与View进行交互,提供给View显示所需的数据以及处理用户输入。
using System.ComponentModel;
public class UserViewModel : INotifyPropertyChanged
{
private User _user = new User();
public UserViewModel()
{
_user.Name = "John Doe";
_user.Age = 30;
}
public User User
{
get => _user;
set
{
if (_user != value)
{
_user = value;
OnPropertyChanged("User");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
4. 数据绑定 (Data Binding)
数据绑定是MVVM模式的核心。它可以自动同步ViewModel中的属性到视图上对应的控件。
<Window.DataContext>
<local:UserViewModel />
</Window.DataContext>
<!-- 其他 UI 定义 -->
5. 命令 (Command)
命令用于在View和ViewModel之间传递用户操作。
using System.Windows.Input;
public class RelayCommand : ICommand
{
private readonly Action<object> _execute;
private readonly Func<object, bool> _canExecute;
public RelayCommand(Action<object> execute) : this(execute, null) { }
public RelayCommand(Action<object> execute, Func<object, bool> canExecute)
{
_execute = execute ?? throw new ArgumentNullException(nameof(execute));
_canExecute = canExecute;
}
public event EventHandler CanExecuteChanged
{
add => CommandManager.RequerySuggested += value;
remove => CommandManager.RequerySuggested -= value;
}
public bool CanExecute(object parameter)
{
return _canExecute == null || _canExecute(parameter);
}
public void Execute(object parameter)
{
_execute?.Invoke(parameter);
}
}
6. 命令绑定 (Command Binding)
<Button Content="Click Me" Command="{Binding MyCommand}" />
public class UserViewModel : INotifyPropertyChanged
{
// ... 其他代码
public ICommand MyCommand { get; private set; }
public UserViewModel()
{
MyCommand = new RelayCommand(param =>
{
MessageBox.Show("Button clicked!");
});
}
}
7. 资源字典 (Resource Dictionaries)
资源字典用于存储如颜色、字体、样式和模板之类的可重用资源。
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="MyTextBoxStyle" TargetType="{x:Type TextBox}">
<Setter Property="Background" Value="LightBlue"/>
<Setter Property="BorderBrush" Value="DarkGray"/>
<Setter Property="FontSize" Value="14"/>
</Style>
</ResourceDictionary>
<Window.Resources>
<ResourceDictionary Source="/Resources/Styles.xaml"/>
</Window.Resources>
<!-- 使用资源字典中的样式 -->
<TextBox Style="{StaticResource MyTextBoxStyle}" />
8. 自定义控件 (Custom Controls)
自定义控件允许扩展现有的WPF控件,以适应特定的UI需求。
using System.Windows.Controls;
using System.Windows;
public class CustomTextBox : TextBox
{
static CustomTextBox()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomTextBox), new FrameworkPropertyMetadata(typeof(CustomTextBox)));
}
public static readonly DependencyProperty IsReadOnlyProperty =
DependencyProperty.Register("IsReadOnly", typeof(bool), typeof(CustomTextBox));
public bool IsReadOnly
{
get { return (bool)GetValue(IsReadOnlyProperty); }
set { SetValue(IsReadOnlyProperty, value); }
}
}
9. 视图加载与生命周期管理
<Window x:Class="MVVMExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<!-- UI 元素 -->
</Grid>
<Window.Resources>
<local:UserViewModel x:Key="MainVM"/>
</Window.Resources>
<Window.DataContext>
<Binding Source="{StaticResource MainVM}"/>
</Window.DataContext>
</Window>
10. 视图模型中的依赖注入
public class UserViewModel : INotifyPropertyChanged
{
private readonly IUserService _userService;
public UserViewModel(IUserService userService)
{
_userService = userService;
}
// 其他代码...
}
使用Unity容器进行依赖注入:
using Unity;
using System.Windows.Threading;
public class AppBootstrapper : UnityBootstrapper
{
protected override void InitializeShell()
{
base.InitializeShell();
var shell = (MainWindow)Shell;
var viewModel = Container.Resolve<UserViewModel>();
shell.DataContext = viewModel;
}
protected override DependencyObject CreateShell()
{
return new MainWindow();
}
}
以上是对C#中MVVM模式的关键知识点及对应的代码示例。通过这些例子,你可以更好地理解和实现MVVM架构。