基本上我绑定了数据网格,使其类似于主题的时间表 - 每行代表一个学期的学科,并且该学期内的每个单元代表一个主题。
我现在正在尝试添加拖放功能,以便您可以将其他主题拖动到网格上,这将更新基础数据结构。
我可以使用一些可视树方法来查找用户正在拖动新主题的DataGridCell,但我不知道如何访问单元格绑定到它的值(主题)以便替换带有新主题的空白/占位符值。有没有办法访问基础值,还是应该重构我创建此程序的整个方法?
答案 0 :(得分:3)
要获取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
属性和行数据项转换为行数据项上的特定值。
编辑:
如果您将数据放入的单元格不是所选单元格,则可以选择使用DataGridRow
获取DataGridCell
所属的VisualTreeHelper
:
var parent = VisualTreeHelper.GetParent(gridCell);
while(parent != null && parent.GetType() != typeof(DataGridRow))
{
parent = VisualTreeHelper.GetParent(parent);
}
var dataRow = parent;
然后你有了这行,可以像上面一样继续。
此外,关于您是否应重新考虑该方法的问题,我建议您使用自定义 WPF行为。
行为提供了一种非常直接的方式来扩展控件的功能,从C#代码扩展到XAML,同时保持代码隐藏清晰简单(如果您关注MVVM,这不仅很好)。行为的设计方式使它们可以重复使用,而不受特定控制的约束。
对于您的特殊情况,我只能告诉您该怎么做:
为你的TextBlock控件(或你想要的DataGridCells中需要的任何控件)写一个DropBehavior
来处理drop。基本思想是根据{{1}中单元格的evnt注册操作。你控制的方法。
OnAttached()
请注意,从行数据和public class DropBehavior : Behavior<TextBlock>
{
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;
}
}
属性解析单个单元格的数据将变得过时。
然后使用DataGrid的Column
的{{1}}将此行为附加到TextBlocks中,然后将其放入单元格中:
ContentTemplate
您可以在
中找到CellStyle
基类
System.Windows.Interactivity.dll
我没有对它进行过测试,但我希望它适合你并且你明白了......