Получить строку из индекса в Silverlight DataGrid

Я пытаюсь реализовать переупорядочивание строк в Silverlight DataGrid. Для этого я расширяю значение по умолчанию DataGridDragDropTarget, и мне нужно переопределить и реализовать следующий метод:

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

}

Как я могу получить DataGridRow из DataGrid и индекса?


person Xavier Poinas    schedule 22.10.2010    source источник


Ответы (2)


Небольшое улучшение ответа Герцмейстера, см. комментарии:

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;
}
person Xavier Poinas    schedule 31.10.2010
comment
Рад, что смог помочь поставить вас на правильный путь. Да, я тоже думал о виртуализации. - person herzmeister; 01.11.2010

Я еще не смотрел на 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
    }
}

Однако я не знаю, как вы хотите реализовать переупорядочение строк. Скорее всего, вы должны сами отслеживать свои индексы и возвращать одно из ваших собственных сохраненных значений индекса в этом методе.

person herzmeister    schedule 29.10.2010
comment
Этот метод не реализован в базовом классе (просто возвращает null). Ваша реализация не всегда будет работать, потому что элементы могут визуально отображаться не в том порядке, в котором они хранятся в коллекции Children, т.е. индекс в Children может отличаться от индекса строки в DataGrid. Это происходит, когда источник данных был изменен после рендеринга строк или из-за виртуализации в панели. Тем не менее, это поставило меня на правильный путь, так что спасибо за это. Строки предоставляют метод GetIndex(), который можно использовать для выбора правильного. - person Xavier Poinas; 01.11.2010