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

WPF中DataGrid选中行无法写入SQL表的问题求助

问题排查与解决方法

核心问题分析

  • 按钮始终启用:RelayCommand的CanExecute状态未随SelectedItems的变化而自动更新
  • 方法未按预期触发:DataGrid选中项未正确同步到ViewModel的SelectedItems集合,且数据写入逻辑缺少提交操作

分步解决

1. 修复DataGrid选中项与ViewModel的同步问题

DataGrid的SelectedItems是只读集合,直接绑定无法实现双向同步,可通过以下两种方式解决:

方式一:通过SelectionChanged事件手动同步

在XAML的DataGrid中添加事件绑定:

<DataGrid ItemsSource="{Binding DataGridItems}"
          SelectionMode="Extended"
          SelectionChanged="DataGrid_SelectionChanged"/>

在视图后台实现事件处理逻辑:

private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var viewModel = DataContext as DataGridViewModel;
    viewModel.SelectedItems.Clear();
    foreach (var item in (sender as DataGrid).SelectedItems)
    {
        viewModel.SelectedItems.Add(item as States);
    }
}

方式二:使用附加属性(MVVM友好方案)

创建附加属性来实现SelectedItems的双向绑定:

public class DataGridSelectionHelper
{
    public static readonly DependencyProperty SelectedItemsProperty =
        DependencyProperty.RegisterAttached("SelectedItems", typeof(ObservableCollection<object>), typeof(DataGridSelectionHelper),
            new PropertyMetadata(null, OnSelectedItemsChanged));

    public static ObservableCollection<object> GetSelectedItems(DependencyObject obj)
    {
        return (ObservableCollection<object>)obj.GetValue(SelectedItemsProperty);
    }

    public static void SetSelectedItems(DependencyObject obj, ObservableCollection<object> value)
    {
        obj.SetValue(SelectedItemsProperty, value);
    }

    private static void OnSelectedItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is DataGrid dataGrid)
        {
            dataGrid.SelectionChanged += (s, args) =>
            {
                var selectedItems = GetSelectedItems(dataGrid);
                selectedItems.Clear();
                foreach (var item in dataGrid.SelectedItems)
                {
                    selectedItems.Add(item);
                }
            };
        }
    }
}

在XAML中引用该附加属性:

<DataGrid ItemsSource="{Binding DataGridItems}"
          local:DataGridSelectionHelper.SelectedItems="{Binding SelectedItems}"/>

2. 修复RelayCommand的CanExecute状态更新问题

当SelectedItems集合内容变化时,需要主动通知RelayCommand重新评估CanExecute状态:

首先确保你的RelayCommand实现包含触发CanExecuteChanged的方法:

public class RelayCommand : ICommand
{
    private readonly Action<object> _execute;
    private readonly Func<object, bool> _canExecute;

    public event EventHandler CanExecuteChanged;

    public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null)
    {
        _execute = execute ?? throw new ArgumentNullException(nameof(execute));
        _canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {
        return _canExecute == null || _canExecute(parameter);
    }

    public void Execute(object parameter)
    {
        _execute(parameter);
    }

    public void RaiseCanExecuteChanged()
    {
        CanExecuteChanged?.Invoke(this, EventArgs.Empty);
    }
}

然后在ViewModel中监听SelectedItems的集合变化,触发命令状态更新:

public DataGridViewModel()
{
    DataGridItems = new ObservableCollection<States>();
    SelectedItems = new ObservableCollection<States>();
    // 监听集合元素变化事件
    SelectedItems.CollectionChanged += SelectedItems_CollectionChanged;
    
    LoadDataFromDatabase();
    SendSelectedRowsToSQLCommand = new RelayCommand(SendSelectedRowsToSQL, CanSendSelectedRows);
}

private void SelectedItems_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    // 通知命令重新评估CanExecute状态
    (SendSelectedRowsToSQLCommand as RelayCommand)?.RaiseCanExecuteChanged();
}

3. 修复数据写入SQL的逻辑问题

SendSelectedRowsToSQL方法中缺少SaveChanges()调用,导致数据仅在内存中添加,未提交到数据库:

public void SendSelectedRowsToSQL(object parameter)
{
    using (var context = new DbProjectEntities())
    {
        foreach (var item in SelectedItems)
        {
            context.orderedStateTbl.Add(new orderedStateTbl
            {
                orderStateId = item.StateID,
                oStateName = item.StateName
            });
        }
        // 添加此行提交数据库更改
        context.SaveChanges();
    }
}

验证要点

  • 确认DataGrid的SelectionMode设置为Single或Extended(默认值为Single)
  • 检查ViewModel的SelectedItems在选中行时是否正确添加了对应元素
  • 测试按钮状态:未选中行时禁用,选中后启用;点击按钮后验证数据是否成功写入SQL表

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 05:55:34