Как применить связывание клавиш в CellTemplate объекта DataGridTemplateColumn?

У меня есть небольшая проблема, из-за которой я не могу найти полную и окончательную информацию о...

Мое требование очень простое: я хочу применить KeyBinding к DataGridTemplateColumn. Цель этого состоит в том, чтобы выполнить команду, когда клавиша Delete ударила для этого столбца - другая команда выполняется, если клавиша Delete удаляется где-либо еще в сетке. Обе команды удаления существуют в виртуальной машине сетки.

Хотя на уровне сетки можно было определить одну привязку клавиш, а затем в командном тесте, к какому столбцу принадлежит активная ячейка, это грязное решение, потому что:

  • это плохо масштабируется, когда сетка используется на нескольких разных страницах

  • рассматриваемый столбец определяется как ресурс в ResourceDictionary

Кроме того, я не видел ничего, что указывало бы на то, что это невозможно... но это ускользает от меня.

Я считаю, что моя проблема в том, что фокус не применяется автоматически к шаблону CellTemplate, когда эта ячейка становится текущей ячейкой сетки. В ячейке есть прямоугольник фокусировки, но внутри ячейки события фокусировки не запускаются (я проверял это). Хотя элементы управления только для чтения, такие как TextBlocks, могут получить фокус, если они этого не делают, связывание клавиш не может быть запущено. Команды для связывания клавиш правильно связаны, поэтому связывание не является проблемой.

Сетка определяется следующим образом:

<DataGrid   x:Name="MyGrid"
            ItemsSource="{Binding Path=FilteredSortedData}"             
            >

    <DataGrid.Columns>
        <StaticResource ResourceKey="StatusColumn" />
        <StaticResource ResourceKey="MySpecialDeleteColumn" />
        <StaticResource ResourceKey="...etc..." />
    </DataGrid.Columns>
</DataGrid>

Тогда столбец:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    x:Class="MyNamespace.GridColumns"
                    >
    <FrameworkElement x:Key="GridColProxy" Name="GridColProxy" DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, NotifyOnSourceUpdated=True, NotifyOnTargetUpdated=True, Mode=OneWay}" />

    <DataGridTemplateColumn x:Key="MySpecialDeleteColumn"
                            x:Shared="False"
                            Header="My Special Delete Column"   
                            IsReadOnly="False"
                            >
        <DataGridTemplateColumn.CellTemplate>             
            <DataTemplate>
                <StackPanel >
                    <!-- keybinding doesn't work at this level  -->
                    <StackPanel.Style >
                        <Style TargetType="StackPanel">
                            <Setter Property="localBehaviours:InputBindingsBehaviour.AttachedKeyBindings">
                                <Setter.Value>
                                    <localBehaviours:KeyBindingObservable  >
                                        <KeyBinding Key="Delete" Command="{Binding Path=DataContext.DeleteItemsCommand, Source={StaticResource GridColProxy}, Mode=OneWay, NotifyOnTargetUpdated=True}" />
                                    </localBehaviours:KeyBindingObservable>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </StackPanel.Style>

                    <Grid >
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>

                        <TextBlock  Grid.Column="0"
                                    Text="{Binding SomeProperty}"
                                    >
                            <TextBlock.Style>
                                <Style TargetType="TextBlock" >
                                    <Style.Triggers>
                                        <DataTrigger Binding="{Binding Path=MySpecialFlag, FallbackValue=false}" Value="True">
                                            <Setter Property="localBehaviours:InputBindingsBehaviour.AttachedKeyBindings">
                                                <Setter.Value>
                                                    <localBehaviours:KeyBindingObservable  >
                                                        <KeyBinding Key="Delete" Command="{Binding Path=DataContext.DeleteItemsCommand, Source={StaticResource GridColProxy}, Mode=OneWay, NotifyOnTargetUpdated=True}" />
                                                    </localBehaviours:KeyBindingObservable>
                                                </Setter.Value>
                                            </Setter>
                                        </DataTrigger>
                                    </Style.Triggers>
                                </Style>
                            </TextBlock.Style>
                        </TextBlock>
                        <Image  Source="{Binding ...}"
                                Grid.Column="1"
                                />
                    </Grid>
                </StackPanel>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>   

        <DataGridTemplateColumn.CellStyle>
            <Style TargetType="{x:Type DataGridCell}" >
                <Style.Triggers>
                    <!-- placing the keybinding here to apply to the grid cell doesn't have any effect... -->
                    <DataTrigger Binding="{Binding Path=MySpecialFlag, FallbackValue=false}" Value="True">
                        <Setter Property="localBehaviours:InputBindingsBehaviour.AttachedKeyBindings">
                            <Setter.Value>
                                <localBehaviours:KeyBindingObservable  >
                                    <KeyBinding Key="Delete" Command="{Binding Path=DataContext.DeleteItemsCommand, Source={StaticResource GridColProxy}, Mode=OneWay, NotifyOnTargetUpdated=True}" />
                                </localBehaviours:KeyBindingObservable>
                            </Setter.Value>
                        </Setter>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </DataGridTemplateColumn.CellStyle>
    </DataGridTemplateColumn>
</ResourceDictionary>  

Заметки:

  • игнорировать localBehaviours:KeyBindingObservable это просто присоединенное свойство, помогающее перехватывать и проверять сочетания клавиш перед назначением их InputBindings свойство прикрепленного элемента управления. Это прекрасно работает, здесь нет проблем.

  • Я показал каждое место, где я пробовал сочетания клавиш, ни одно из них не сработало (сработало). Привязки DataTrigger работают правильно, поэтому просто игнорируйте их.

  • CellEditingTemplate был опущен для краткости

Итак, у меня есть вопрос:

  • как заставить элементы CellTemplate получить фокус (на клавиатуре), желательно с XAML? Или есть способ применить связывание клавиш на уровне ячеек, чтобы оно работало независимо от отображаемого шаблона?

Если решение XAML невозможно, можно использовать небольшое количество кода, запускаемого событиями (PreviewKeyDown и т. Д.) В коде ResourceDictionary.

0 ответов

Другие вопросы по тегам