You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF MVVM架构下如何将数据库上下文绑定至DataGrid?

第一步:理清Model职责,消除冗余

先拆分混乱的Model结构,明确各自职责:

  1. 实体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; }
}
  1. 业务/数据访问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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 05:17:22