我有点卷曲的问题,我找不到任何关于...的完整和明确的信息。
我的要求非常简单:我想将KeyBinding应用于DataGridTemplateColumn。这样做的目的是在为该列命中 Delete 键时执行命令 - 如果在网格上的任何其他地方命中 Delete ,则执行不同的命令。两个删除命令都存在于网格的VM中。
虽然我可以在网格级别定义一个键绑定,然后在命令测试活动单元格所属的列中,这是一个混乱的解决方案,因为:
在网格用于多个不同页面时不能很好地扩展
有问题的列被定义为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
如果无法使用XAML解决方案,则可以使用ResourceDictionary背后的代码中的少量事件触发(PreviewKeyDown等)代码。