WPF DataGrid:如何从ViewModel选中[0,0]位置的单元格
WPF DataGrid MVVM模式下初始选中[0,0]单元格及获取选中内容
需求场景
- 获取选中单元格的值
- 获取选中单元格所在列的所有值
现有DataGrid配置
<DataGrid Margin="0,5,0,0" IsReadOnly="True" ItemsSource="{Binding DataTableViewModel.DataView}" AutoGenerateColumns="true" ScrollViewer.CanContentScroll="True" CanUserResizeColumns="True" CanUserReorderColumns="True" CanUserSortColumns="True" CanUserAddRows="false" ColumnWidth="auto" EnableRowVirtualization="True" EnableColumnVirtualization="True" VirtualizingPanel.IsVirtualizingWhenGrouping="True" VirtualizingPanel.VirtualizationMode="Standard" VirtualizingPanel.IsVirtualizing="True" SelectionMode="Single" SelectionUnit="Cell" VerticalAlignment="Top"/>
ViewModel代码片段
class DataTableViewModel : PropertyChangedBase { // notify child classes the DataTable has been loaded protected event EventHandler<EventArgs> DataTableLoaded; public DataView DataView { get { return _dataView; } set { _dataView = value; NotifyPropertyChanged(); } } DataView _dataView; DataTable _dataTable; public DataTable DataTable { get { return _dataTable; } set { _dataTable = value; DataView = value.DefaultView; if (DataTableLoaded== null) return; DataTableLoaded.Invoke(this, new EventArgs()); NotifyPropertyChanged(); // Can I put something here to set the selected cell? } } }
核心问题
DataGrid首次显示时,如何在ViewModel中将活动单元格设置为[0,0]位置?同时需要明确应该绑定哪个属性(SelectedItem/CurrentCell/SelectedIndex)来标识选中单元格,进而实现获取选中单元格值和所在列所有值的逻辑。
解决方案
1. 绑定CurrentCell实现单元格选中与状态跟踪
在SelectionUnit="Cell"模式下,CurrentCell是唯一能直接标识选中单元格的可绑定属性(SelectedItem仅对应选中行,SelectedIndex仅对应行索引,都无法定位到单元格)。它的类型是DataGridCellInfo结构体,可直接在ViewModel中定义双向绑定的属性。
步骤1:ViewModel中添加CurrentCell属性及变更逻辑
private DataGridCellInfo _currentCell; public DataGridCellInfo CurrentCell { get => _currentCell; set { if (_currentCell != value) { _currentCell = value; NotifyPropertyChanged(); OnCurrentCellChanged(); } } } private void OnCurrentCellChanged() { if (!CurrentCell.IsValid) return; // 获取选中单元格的值 var columnName = CurrentCell.Column.SortMemberPath; var cellValue = ((DataRowView)CurrentCell.Item)[columnName]; // 获取选中列的所有值 var columnValues = DataView.Cast<DataRowView>() .Select(row => row[columnName]) .ToList(); // 此处添加更新对应列表的业务逻辑 }
步骤2:XAML中绑定CurrentCell
给DataGrid添加双向绑定:
<DataGrid ... CurrentCell="{Binding DataTableViewModel.CurrentCell, Mode=TwoWay}" .../>
2. 数据加载完成后设置初始[0,0]单元格
在ViewModel的DataTable属性赋值完成后,判断数据是否有效,直接构造DataGridCellInfo赋值给CurrentCell:
public DataTable DataTable { get { return _dataTable; } set { _dataTable = value; DataView = value.DefaultView; DataTableLoaded?.Invoke(this, new EventArgs()); NotifyPropertyChanged(); // 设置初始选中[0,0]单元格 if (DataView?.Count > 0 && DataView.Table.Columns.Count > 0) { var firstRow = DataView[0]; var firstColumn = DataView.Table.Columns[0]; CurrentCell = new DataGridCellInfo(firstRow, firstColumn); } } }
说明:因为开启了AutoGenerateColumns="true",DataGrid的列与DataTable的列一一对应,直接用DataView.Table.Columns[0]就能定位到第一列,无需依赖DataGrid控件实例。
内容的提问来源于stack exchange,提问作者Jase99
相关产品推荐
相关产品推荐

