Команда за обвързване вътре в 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 благодарение на поддръжката на обвързване на предците.

Пример

<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 (известен още като 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