1. WPF 的 MVVM 模式是什么?各层的职责是什么?如何实现数据绑定?
MVVM(Model-View-ViewModel)模式是 WPF 推荐的架构模式,主要目的是实现界面与业务逻辑的分离,提升代码的可维护性和可测试性。
- Model(模型):负责业务数据和业务逻辑,通常是实体类或数据访问层,不包含界面相关代码。
- View(视图):负责界面展示,通常是 XAML 文件,只负责 UI 的布局和样式,不包含业务逻辑。
- ViewModel(视图模型):连接 View 和 Model,负责处理界面逻辑、命令、数据转换等。ViewModel 通过实现 INotifyPropertyChanged 接口,实现属性变更通知,支持数据绑定。
数据绑定实现方式:
- 在 XAML 中通过 {Binding} 语法将控件属性绑定到 ViewModel 的属性。
- ViewModel 属性变更时,通过 PropertyChanged 事件通知 View 自动更新。
- 例如:
// ViewModel
public class PersonViewModel : INotifyPropertyChanged
{
private string name;
public string Name
{
get => name;
set { name = value; OnPropertyChanged(nameof(Name)); }
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); }
<!-- XAML -->
<TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}" />
好的,下面细化 WPF MVVM 中的数据绑定方式,并给出结合异步数据加载的代码示例。
数据绑定方式细化
WPF 的数据绑定支持多种模式,包括:
- OneWay:View 只从 ViewModel 获取数据。
- TwoWay:View 和 ViewModel 之间双向同步。
- OneWayToSource:ViewModel 只从 View 获取数据。
- OneTime:只在绑定时获取一次数据。
常用绑定方式是在 XAML 中通过 {Binding} 语法,将控件属性绑定到 ViewModel 的属性。ViewModel 需实现 INotifyPropertyChanged 接口,属性变更时通知 UI 自动更新。
异步数据绑定代码示例
假设有一个按钮,点击后异步加载数据并显示在界面上。
1. ViewModel 示例
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
public class AsyncViewModel : INotifyPropertyChanged
{
private string _data;
public string Data
{
get => _data;
set { _data = value; OnPropertyChanged(); }
}
public async Task LoadDataAsync()
{
// 模拟异步数据加载
await Task.Delay(2000); Data = "异步加载完成的数据";
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); }
2. XAML 绑定示例
<Window x:Class="AsyncBindingDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="异步数据绑定示例" Height="200" Width="300">
<StackPanel Margin="20">
<Button Content="加载数据" Click="Button_Click"/>
<TextBlock Text="{Binding Data, Mode=OneWay}" Margin="0,20,0,0" FontSize="16"/>
</StackPanel>
</Window>
3. 代码后端示例
using System.Windows;
namespace AsyncBindingDemo
{
public partial class MainWindow : Window
{
private AsyncViewModel viewModel = new AsyncViewModel();
public MainWindow()
{
InitializeComponent();
DataContext = viewModel;
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
await viewModel.LoadDataAsync();
}
}
}
说明
- TextBlock 的 Text 属性通过 {Binding Data} 绑定到 ViewModel 的 Data 属性。
- 点击按钮后,调用 ViewModel 的异步方法 LoadDataAsync,数据加载完成后自动更新界面。
- 这种方式充分利用了 WPF 的数据绑定和异步编程能力,实现了界面与逻辑的解耦和高响应性。