Как найти его владельца DataGrid и DataGridRow из DataGridCell в WPF?

В обработчике событий для Command для DataGrid я получаю DataGridCell в ExecutedRoutedEventArgs. Однако я не мог понять, как получить связанные с ним DataGrid и DataGridRow. Ваша помощь очень ценится.

Ответ 1

Вероятно, вы хотите установить привязку RelativeSource, которая может получить "родительскую сетку/строку" с помощью {RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}, но ваш вопрос заставил меня думать...

Вы можете:

Использование Reflection:

var gridCell = ....;
var parentRow = gridCell
         .GetType()
         .GetProperty("RowOwner", 
               BindingFlags.NonPublic | BindingFlags.Instance)
         .GetValue(null) as DataGridRow;

Используйте VisualTreeHelper:

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

Ответ 2

Вот что я думаю, это полный ответ...

    private void Copy(object sender, ExecutedRoutedEventArgs e)
    {
        DataGrid grid = GetParent<DataGrid>(e.OriginalSource as DependencyObject);
        DataGridRow row = GetParent<DataGridRow>(e.OriginalSource as DependencyObject);
    }

    private T GetParent<T>(DependencyObject d) where T:class
    {
        while (d != null && !(d is T))
        {
            d = VisualTreeHelper.GetParent(d);
        }
        return d as T;
    }

Ответ 3

Один из способов сделать это - передать один или оба необходимых элемента в качестве параметра CommandParameter:

<MouseBinding 
    MouseAction="LeftDoubleClick" 
    Command="cmd:CustomCommands.Open" 
    CommandParameter="{Binding ElementName=MyDataGrid}}" />

Если вам нужны оба варианта, вы можете добавить многозначный конвертер, который объединяет их в Tuple (или оставить его как объект [])

Затем в своем коде вы можете получить к нему доступ, используя e.Parameter