WPF MVVM架构下如何将数据库上下文绑定至DataGrid?
第一步:理清Model职责,消除冗余
先拆分混乱的Model结构,明确各自职责:
- 实体Model(Company):纯数据载体,对应数据库表结构,单独放到
Company.cs文件:
public class Company { public int? ID { get; set; } public string? Name { get; set; } public string? Address { get; set; } public string? Postal { get; set; } public string? Location { get; set; } public string? Country { get; set; } public string? Created { get; set; } }
- 业务/数据访问Model(CompanyModel):负责和数据库交互、加载数据,不用重复单个Company的字段,只维护公司列表,同时实现
INotifyPropertyChanged让ViewModel感知数据变化:
public class CompanyModel : INotifyPropertyChanged { private IList<Company>? _companies; private readonly MYSQLDAL.Models.dataContext _context; public IList<Company>? Companies { get => _companies; set { _companies = value; OnPropertyChanged(nameof(Companies)); } } public CompanyModel(MYSQLDAL.Models.dataContext context) { _context = context; } public async Task loadCompanies() { // 替换为你实际的数据库查询逻辑,比如EF的ToListAsync Companies = await _context.Companies.ToListAsync(); } public event PropertyChangedEventHandler? PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
第二步:修正ViewModel,实现数据通知和绑定
ViewModel要实现INotifyPropertyChanged,暴露供UI绑定的集合属性,并处理数据加载:
internal class CompanyViewModel : INotifyPropertyChanged { private readonly CompanyModel _model; private ObservableCollection<Company>? _companyDataGrid; public ObservableCollection<Company>? CompanyDataGrid { get => _companyDataGrid; set { _companyDataGrid = value; OnPropertyChanged(nameof(CompanyDataGrid)); } } public CompanyViewModel() { _model = new CompanyModel(new MYSQLDAL.Models.dataContext()); // 页面初始化时自动加载数据 LoadCompaniesAsync(); } private async void LoadCompaniesAsync() { await _model.loadCompanies(); // 转成ObservableCollection,确保UI能感知集合变更 if (_model.Companies != null) { CompanyDataGrid = new ObservableCollection<Company>(_model.Companies); } } public event PropertyChangedEventHandler? PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
第三步:确保View的DataContext和绑定正确
在CompanyView.xaml根元素设置DataContext,让UI能找到ViewModel:
<Page x:Class="你的命名空间.CompanyView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:你的命名空间"> <Page.DataContext> <local:CompanyViewModel /> </Page.DataContext> <!-- 你的DataGrid代码无需修改,保持原绑定即可 --> <DataGrid x:Name="companyDataGrid" IsReadOnly="True" AutoGenerateColumns="False" ItemsSource="{Binding CompanyDataGrid, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left"> <!-- 列定义不变 --> </DataGrid> </Page>
关键注意点
- ViewModel不要处理UI事件(比如原代码里的
Page_Loaded),只负责数据和业务逻辑,数据加载直接在构造时异步执行 - 用
ObservableCollection替代普通IEnumerable,集合增删改会自动通知UI更新 - 严格划分层级:实体Model存数据,业务Model管数据访问,ViewModel做数据中转和UI通知
内容的提问来源于stack exchange,提问作者Colm Ukrainec
相关产品推荐
相关产品推荐

