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

WPF中如何从XML加载表格并支持编辑与保存(MVVM模式)

核心实现指引(MVVM范式下的DataGrid+XML读写)

1. 调整XAML绑定(贴合MVVM)

你的现有DataGrid绑定可以优化为直接关联ViewModel的集合属性,同时补充双向绑定确保编辑同步:

<TabItem Header="Device Info" Width="100" Height="25"
         Selected="DeviceTab_Selected" Unloaded="DeviceTab_Unloaded">
    <DataGrid Name="DeviceInfoGrid" 
              ItemsSource="{Binding DeviceData}" 
              AlternatingRowBackground="LightBlue" 
              AlternationCount="2"
              AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Alias" Binding="{Binding Alias, Mode=TwoWay}"/>
            <DataGridTextColumn Header="Interface Type" Binding="{Binding InterfaceType, Mode=TwoWay}"/>
            <DataGridTextColumn Header="Resource ID" Binding="{Binding VisaResource, Mode=TwoWay}"/>
            <DataGridTextColumn Header="MFG" Binding="{Binding Make, Mode=TwoWay}"/>
            <DataGridTextColumn Header="Model" Binding="{Binding Model, Mode=TwoWay}"/>
            <DataGridTextColumn Header="Cal Date" Binding="{Binding CalDate, Mode=TwoWay}"/>
            <DataGridTextColumn Header="Cal Due Date" Binding="{Binding CalDueDate, Mode=TwoWay}"/>
        </DataGrid.Columns>
    </DataGrid>
</TabItem>
  • 给TabItem添加Selected/Unloaded事件,触发数据加载与保存
  • DataGrid的ItemsSource绑定到ViewModel的DeviceData属性
  • 每个列绑定设置Mode=TwoWay,确保用户编辑能同步回数据源

2. 定义ViewModel核心类

创建MainWindowViewModel,实现INotifyPropertyChanged(WPF绑定必备),封装数据存储与XML读写逻辑:

using System.ComponentModel;
using System.Data;
using System.Windows;

public class MainWindowViewModel : INotifyPropertyChanged
{
    private DataTable _deviceData;
    public DataTable DeviceData
    {
        get => _deviceData;
        set
        {
            _deviceData = value;
            OnPropertyChanged(nameof(DeviceData));
        }
    }

    private readonly string _xmlFilePath = "Devices.xml"; // 替换为你的XML文件路径

    // 从XML加载数据到DataTable
    public void LoadDeviceData()
    {
        if (System.IO.File.Exists(_xmlFilePath))
        {
            DataSet ds = new DataSet();
            ds.ReadXml(_xmlFilePath);
            DeviceData = ds.Tables[0];
        }
        else
        {
            // 文件不存在时创建空表结构
            DeviceData = CreateEmptyDeviceTable();
        }
    }

    // 将DataTable数据保存到XML
    public void SaveDeviceData()
    {
        try
        {
            DataSet ds = new DataSet();
            ds.Tables.Add(DeviceData.Copy());
            ds.WriteXml(_xmlFilePath);
        }
        catch (System.Exception ex)
        {
            MessageBox.Show($"保存失败: {ex.Message}");
        }
    }

    // 创建空的仪器信息表结构
    private DataTable CreateEmptyDeviceTable()
    {
        DataTable table = new DataTable("Devices");
        table.Columns.Add("Alias", typeof(string));
        table.Columns.Add("InterfaceType", typeof(string));
        table.Columns.Add("VisaResource", typeof(string));
        table.Columns.Add("Make", typeof(string));
        table.Columns.Add("Model", typeof(string));
        table.Columns.Add("CalDate", typeof(string));
        table.Columns.Add("CalDueDate", typeof(string));
        return table;
    }

    // INotifyPropertyChanged接口实现
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

3. 主窗口代码(ViewModel关联+事件触发)

在MainWindow.xaml.cs中完成ViewModel与窗口的绑定,并处理Tab页的加载/保存事件:

public partial class MainWindow : Window
{
    private MainWindowViewModel _viewModel;

    public MainWindow()
    {
        InitializeComponent();
        _viewModel = new MainWindowViewModel();
        DataContext = _viewModel; // 将ViewModel设为窗口数据上下文
    }

    // 标签页选中时加载数据
    private void DeviceTab_Selected(object sender, RoutedEventArgs e)
    {
        _viewModel.LoadDeviceData();
    }

    // 标签页卸载时保存数据
    private void DeviceTab_Unloaded(object sender, RoutedEventArgs e)
    {
        _viewModel.SaveDeviceData();
    }
}

4. 方向确认

你的思路完全正确:用DataTable作为DataGrid的数据源,借助DataSet的ReadXml/WriteXml快速实现XML读写,符合MVVM范式下UI与逻辑分离的要求。

额外注意:

  • 如果后续需要更复杂的业务验证或实体行为,可以将DataTable替换为ObservableCollection<DeviceModel>(自定义实体类),但当前场景下DataTable是更轻量的选择
  • 可在保存前增加确认提示,避免误操作导致数据覆盖

内容的提问来源于stack exchange,提问作者ReelThymeOS

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 18:07:07