Привязка к команде в сетке данных - PullRequest
18 голосов
/ 24 февраля 2009

Я использую шаблон M-V-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 ]

38 голосов
/ 24 февраля 2009

Да, тебе просто нужно подняться на один уровень. Сначала я попробую привязку с 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.

1 голос
/ 09 мая 2017

Мне нравится определять модель представления в текстовом виде элемента управления с именем 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}"  

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...