Привязка к команде в сетке данных

Я использую шаблон MV-VM в приложении WPF. Я связываю ViewModel с ContentControl и использую шаблон данных, определенный в ресурсах окна, для визуализации представления (UserControl) для этой ViewModel.

В ViewModel у меня есть коллекция предметов. Я связываю эту коллекцию с сеткой данных, представленной в наборе инструментов WPF. Также в модели представления у меня определена команда RemoveItem, которая принимает аргумент для удаления идентификатора элемента.

Как бы я связался с этой командой в сетке данных? Контекст данных сетки - это то собрание, что-то вроде:

<Button Command="{Binding Path=RemoveCommand}" CommandParameter="{Binding Path=id}">X</Button>

не работает - не может найти команду Я думаю, что мне нужно сделать привязку RelativeSource, но как это будет выглядеть? Будет ли тип Ancestor UserControl или ContentControl? Где моя ViewModel находится как DataContext?

Или я далеко отсюда?

2 ответа

Решение

Да, тебе просто нужно подняться на один уровень. Я бы попробовал связать с ElementName сначала и прибегнуть к RelativeSource только при необходимости. Например, я бы предпочел это:

<DataGrid x:Name="_grid">
    ...
        <Button Command="{Binding DataContext.RemoveItem, ElementName=_grid}"/>
    ...
</DataGrid>

Тем не менее, компилятор XAML может связывать свои ручки в узлах, когда речь идет об именах элементов и области видимости в элементах управления, поэтому вам, возможно, придется прибегнуть к RelativeSource:

<DataGrid x:Name="_grid">
    ...
  <Button Command="{Binding DataContext.RemoveItem, 
                    RelativeSource={RelativeSource FindAncestor, 
                                    AncestorType={x:Type DataGrid}}
                   }"/>
    ...
</DataGrid>

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

Мне нравится определять viewmodel в datacontext элемента управления с именем ViewModel. Привязка легче написать с помощью ElementName

...
<UserControl.DataContext>
    <local:UserControlViewModel x:Name="ViewModel"/>
</UserControl.DataContext>
...

...
<DataGridTemplateColumn  Width="30">
    <DataGridTemplateColumn.CellTemplate>
         <DataTemplate>
             <Button Command="{Binding RemoveCommand, ElementName=ViewModel}" 
                     CommandParameter="{Binding}">Remove</Button>
         </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
...

Обратите внимание, что в этом случае параметр командной строки является целым объектом данных строки. Иногда лучше, чем

CommandParameter="{Binding Id}"  

потому что вам не нужно снова искать данные.

Другие вопросы по тегам