如何在代码中访问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的CellStyle
的ContentTemplate
将此行为附加到TextBlocks中,然后将其放入单元格中:
您可以在中找到Behavior
基类
System.Windows.Interactivity.dll
我没有测试过,但我希望它对你有用,你就明白了……