Команда привязки внутри 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>

person katit    schedule 28.09.2011    source источник
comment
Почему вы используете EventTrigger вместо свойства Command кнопки?   -  person Jehof    schedule 04.10.2011
comment
@Jehof Использование команды представляет ту же проблему. Я использую триггер события для согласованности во всем приложении   -  person katit    schedule 04.10.2011
comment
Привет @katit, ты не забыл наградить меня бонусными баллами? ;)   -  person Justin XL    schedule 05.10.2011
comment
@ Xin Нет, я этого не делал, это требует 12-часового ожидания :)   -  person katit    schedule 05.10.2011
comment
хе-хе, спасибо @katit, я этого не знал! :)   -  person Justin XL    schedule 05.10.2011


Ответы (2)


Я почти уверен, что внутри DataGrid вам все еще нужен DataContextProxy, чтобы привязки работали. Привязка ElementName не работает (да, она работает для ListBox шаблонов, но не DataGrid, это потому, что DataGridTemplateColumn отсутствует в визуальном дереве) даже в Silverlight 4.

ОБНОВЛЕНИЕ

В Silverlight 5 DataContextProxy не требуется в DataGrid благодаря поддержке привязки Ancestor.

Пример

<Button Command="{Binding DataContext.CancelCommand, RelativeSource={RelativeSource AncestorType=sdk:DataGrid}}" />
person Justin XL    schedule 04.10.2011
comment
Значение RelativeSourceMode по умолчанию зависит от платформы, поэтому его также следует установить, например ‹Button Command={Binding DataContext.CancelCommand, RelativeSource={RelativeSource AncestorType=sdk:DataGrid, Mode=FindAncestor}} /› - person Alexander Zwitbaum; 22.01.2013

я думаю проблема в этой строчке

<i:InvokeCommandAction Command="{Binding ElementName=Control, Path=DataContext.ItemSelectedCommand}" CommandParameter="{Binding}" />

потому что в вашем XAML нет элемента, определенного с именем Control (aka. x:Name="Control").

Вы должны изменить ElementName=Control на ElementName=LayoutRoot, если команда определена в DataContext, привязанном к LayoutRoot.

Я не знаю, почему это работает в ListBox.

person Jehof    schedule 04.10.2011
comment
У меня есть x:Name = Control в моем пользовательском элементе управления. И это работает для ListBox - person katit; 04.10.2011