在Silverlight DataGrid中根据索引获取行

3

我正在尝试在Silverlight DataGrid中实现行重排。为此,我正在扩展默认的DataGridDragDropTarget,并需要覆盖并实现以下方法:

protected override DataGridRow ContainerFromIndex(DataGrid itemsControl, int index)
{

}

我怎样从DataGrid中获取DataGridRow和索引?

2个回答

5
Herzmeister的答案有所改进,详情见评论:
protected override DataGridRow ContainerFromIndex(DataGrid itemsControl, int index)
{
    var rowsPresenter = itemsControl.GetVisualDescendants().OfType<DataGridRowsPresenter>().FirstOrDefault();
    if (rowsPresenter != null)
    {
        return rowsPresenter.Children.OfType<DataGridRow>()
                .Where(row => row.GetIndex() == index).SingleOrDefault();
    }
    return null;
}

很高兴我能帮助你找到正确的方向。是的,我也在想虚拟化的问题。 - herzmeister

3
我还没有看过 DataGridDragDropTarget,但你不是可以只做
protected override DataGridRow ContainerFromIndex(DataGrid itemsControl, int index)
{
    var row = base.ContainerFromIndex(itemsControl, index);
    if (row != null)
    {
        // do something with row
    }
}

如果由于某些原因没有实现该功能,您可以尝试以下方法:

// requires Assembly System.Windows.Controls.Toolkit.dll

using System.Windows.Controls.Primitives;
// ...

protected override DataGridRow ContainerFromIndex(DataGrid itemsControl, int index)
{
    var rowsPresenter =
        itemsControl.GetVisualDescendants()
            .OfType<DataGridRowsPresenter>().FirstOrDefault();
    if (rowsPresenter != null)
    {
        var row = rowsPresenter.Children[index];
        // do something with row
    }
}

不过我不知道你如何实现行的重新排序。很有可能你必须自己跟踪索引,并在该方法中返回自己存储的一个索引值。


1
该方法在基类中未实现(仅返回null)。您的实现不总是有效,因为项目可能不会以与Children集合中存储的顺序相同的方式在视觉上显示,即Children中的索引可能与DataGrid中行的索引不同。当数据源在行呈现后已更改或由于面板中的虚拟化而发生这种情况。但是它确实让我找到了正确的方向,所以谢谢。行公开了GetIndex()方法,可用于选择正确的行。 - Xavier Poinas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接