Команда привязки внутри DataGridTemplateColumn
У меня есть View (включен XAML), прикрепленный к моим ViewModel с помощью команд. Мне нужно вызвать команду, когда нажата кнопка в строке DataGrid. Я использую для этого поведение (регулярное командование имеет такую же проблему). Когда я нажимаю кнопку в DataGrid - моя команда не запускается.
Чтобы проиллюстрировать проблему - я поместил ListBox на нижнюю часть с ТОЧНЫМ таким же обязательным материалом - и да, команда работает. Итак, это что-то с DataGrid/DataGridTemplateColumn
<Grid x:Name="LayoutRoot" Background="White" DataContext="{Binding}">
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<Button Content="Cancel" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<ei:CallMethodAction MethodName="Cancel" TargetObject="{Binding}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</StackPanel>
<sdk:DataGrid AutoGenerateColumns="False" IsReadOnly="True" ItemsSource="{Binding Data}" Grid.Row="1">
<sdk:DataGrid.Columns>
<sdk:DataGridTemplateColumn CanUserReorder="True" CanUserResize="True" CanUserSort="True" Width="Auto">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="Select">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction Command="{Binding ElementName=Control, Path=DataContext.ItemSelectedCommand}" CommandParameter="{Binding}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
<sdk:DataGridTextColumn Binding="{Binding DeviceId}" CanUserReorder="True" CanUserResize="True" CanUserSort="True" Header="Device" Width="Auto" FontWeight="Bold" />
<sdk:DataGridTextColumn Binding="{Binding SerialNumber}" CanUserReorder="True" CanUserResize="True" CanUserSort="True" Header="Serial Number" Width="Auto" />
<sdk:DataGridTextColumn Binding="{Binding LastActivityOn}" CanUserReorder="True" CanUserResize="True" CanUserSort="True" Header="Last Activity" Width="Auto" />
<sdk:DataGridTextColumn Binding="{Binding ClientVersion}" CanUserReorder="True" CanUserResize="True" CanUserSort="True" Header="Client Version" Width="Auto" />
<sdk:DataGridTextColumn Binding="{Binding OSVersion}" CanUserReorder="True" CanUserResize="True" CanUserSort="True" Header="OS Version" Width="Auto" />
</sdk:DataGrid.Columns>
</sdk:DataGrid>
<ListBox Grid.Row="2" ItemsSource="{Binding Data}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding DeviceId}"></TextBlock>
<Button Content="Select">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction Command="{Binding ElementName=Control, Path=DataContext.ItemSelectedCommand}" CommandParameter="{Binding}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
Ответы
Ответ 1
Я уверен, что внутри DataGrid
вам все равно нужен DataContextProxy, чтобы заставить привязки работать. Связывание ElementName не работает (да, он работает для шаблонов ListBox
, но не DataGrid
, это потому, что DataGridTemplateColumn не находится в визуальном дереве), даже в Silverlight 4.
UPDATE
В Silverlight 5, DataContextProxy
не требуется в DataGrid
благодаря поддержке привязки Ancestor.
Пример
<Button Command="{Binding DataContext.CancelCommand, RelativeSource={RelativeSource AncestorType=sdk:DataGrid}}" />
Ответ 2
Я думаю, проблема в этой строке
<i:InvokeCommandAction Command="{Binding ElementName=Control, Path=DataContext.ItemSelectedCommand}" CommandParameter="{Binding}" />
причина в вашем XAML не является элементом, определяемым с помощью Control Name (aka. x: Name= "Control" ).
Вы должны изменить ElementName = Control на ElementName = LayoutRoot, если команда определена в DataContext, привязанной к LayoutRoot.
Я не знаю, почему это работает в ListBox.