如何在代码中访问DataGridCell的数据对象?

基本上我绑定了数据网格,使其类似于主题的时间表 – 每行代表一个学期的学科,并且该学期内的每个单元代表一个主题。

我现在正在尝试添加拖放function,以便您可以将其他主题拖动到网格上,这将更新基础数据结构。

我可以使用一些可视树方法来查找用户正在拖动新主题的DataGridCell,但我不知道如何访问单元格绑定到它的值(主题)以替换空白/占位符值与新主题。 有没有办法访问基础值,还是应该重构我创建此程序的整个方法?

网格和要拖动到其上的主题的示例

要获取DataGridCell的数据,可以使用它的DataContext和Column属性。 如何做到这一点完全取决于您的行数据是什么,即您放在DataGrid的ItemsSource集合中的项目。 假设您的项目是object[]数组:

 // Assuming this is an array of objects, object[],this gets you the // row data as you have them in the DataGrid's ItemsSource collection var rowData = (object[]) DataGrid.SelectedCells[0].Item; // This gets you the single cell object var celldata = rowData[DataGrid.SelectedCells[0].Column.DisplayIndex]; 

如果行数据更复杂,则需要编写一个根据方法,该方法将Column属性和行数据项转换为行数据项上的特定值。


编辑:

如果您将数据放入的单元格不是所选单元格,则可以使用VisualTreeHelper获取DataGridCell所属的DataGridCell

 var parent = VisualTreeHelper.GetParent(gridCell); while(parent != null && parent.GetType() != typeof(DataGridRow)) { parent = VisualTreeHelper.GetParent(parent); } var dataRow = parent; 

然后你有行,可以按上述步骤操作。


此外,关于您是否应重新考虑该方法的问题,我建议使用自定义WPF行为

行为提供了一种非常直接的方式来扩展控件的function来自C#代码,而不是XAML,同时保持您的代码隐藏清晰简单(如果您关注MVVM,这不仅很好)。 行为的设计方式使它们可以重复使用,而不受特定控制的约束。

这是一个很好的介绍

对于您的特殊情况,我只能告诉您该怎么做:

为TextBlock控件(或者你想要的DataGridCells中的任何控件)编写一个DropBehavior ,它处理drop。基本思想是根据控件的OnAttached()方法中的单元格的evnt注册操作。

 public class DropBehavior : Behavior { protected override void OnAttached() { AssociatedObject.MouseUp += AssociatedObject_MouseUp; } private void AssociatedObject_MouseUp(object sender, MouseButtonEventArgs e) { // Handle what happens on mouse up // Check requirements, has data been dragged, etc. // Get underlying data, now simply as the DataContext of the AssociatedObject var cellData = AssociatedObject.DataContext; } } 

请注意,从行数据和Column属性解析单个单元格的数据将变得过时。

然后使用DataGrid的CellStyleContentTemplate将此行为附加到TextBlocks中,然后将其放入单元格中:

      

您可以在中找到Behavior基类

System.Windows.Interactivity.dll

我没有测试过,但我希望它对你有用,你就明白了……