Ответ от @Darren хорошо работает в большинстве случаев и должен быть предпочтительным методом, если это возможно.Однако это не рабочее решение, при котором все следующие (нишевые) условия выполняются:
- DataGrid с DataGridTemplateColumn
- .NET4
- Windows XP
... и, возможно, при других обстоятельствах.Теоретически это должно произойти сбой во всех версиях Windows;но по моему опыту подход ElementName работает в DataGrid в Windows 7 и выше, но не в XP.
В следующем вымышленном примере мы пытаемся привязать к ICommand называется ShowThingCommand в UserControl.DataContext (который является моделью представления):
<UserControl x:Name="ThisUserControl" DataContext="whatever...">
<DataGrid ItemsSource="{Binding Path=ListOfThings}">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Thing">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button
Command="{Binding ElementName=ThisUserControl, Path=ShowThingCommand}"
CommandParameter="{Binding Path=ThingId}"
Content="{Binding Path=ThingId}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</UserControl>
Из-за DataTemplate не находясь в том же VisualTree, что и основной элемент управления, невозможно сослаться обратно на элемент управления с помощью ElementName .
Чтобы решить эту проблему, малоизвестный .NET 4 и выше {x: Ссылка} .Изменение приведенного выше примера:
<UserControl x:Name="ThisUserControl" DataContext="whatever...">
<DataGrid ItemsSource="{Binding Path=ListOfThings}">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Thing">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button
Command="{Binding Source={x:Reference ThisUserControl}, Path=ShowThingCommand}"
CommandParameter="{Binding Path=ThingId}"
Content="{Binding Path=ThingId}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</UserControl>
Для справки см. Следующие сообщения stackoverflow:
Вопрос 19244111
Вопрос 5834336
... и объяснение того, почему ElementName не работает в этих обстоятельствах, см. в этом блоге , который содержит обходной путь до .NET 4.