##前提
環境:VS2019
言語:C# WPF
フレームワーク:MVVM
##最終的に達成したい事
TextBox上で[Shift + ↓]と入力した際に、データグリッド上にその入力を反映させたい
##悩んでいる事
現状、テキストボックスにフォーカスがありながらも、[↓]ボタンを押せばデータグリッドで[↓]を押した事と同様の処理を KeyDownDownArrowCommand で行っています。
UserControlにInputBindingsを定義しておいて、そこで定義した入力を後述するInputBindingsBehavior
で優先的に処理させる事で解決しています。
優先させない場合、該当コントロールのInputBindingsが実行されてしまうので、InputBindingsを上書きをしているようなイメージです。
このGIFの最後に複数行をマウスで選択していますが、
これと同じ動作をテキストボックス上で[Shift + ↓]と入力してデータグリッドを複数選択させる事は可能でしょうか。
以下のどちらかの方法で解決できるのではないのかと考えていますが、理解力不足で組めません。
① テキストボックスのInputBindingsを、指定したコントロール(ここではDataGrid)のInputBindingsに置き換える、もしくは呼ぶ
② 1列チェックボックスを増やし、VMから[Ctrl + ↓]で移動した際の行を選択させる。Xaml側ではGrid.RowStyleでその行のチェックボックスのチェックを見て行選択かどうかを切り替える
また他に、方法などはありますでしょうか。
###コード
簡略化していますが、Xamlは以下のようにしています。
XAML
1<UserControl x:Class="MegaClibor.Views.RecentFile" 2 b:InputBindingsBehavior.TakesInputBindingPrecedence="True" 3 > 4 <!--キーイベントの割り当て--> 5 <UserControl.InputBindings> 6 <KeyBinding Key="Enter" Command="{Binding KeyDownFileOpenCommand}"/> 7 <KeyBinding Key="Escape" Command="{Binding KeyDownEscapeCommand}"/> 8 <KeyBinding Key="Up" Command="{Binding KeyDownUpArrowCommand}"/> 9 <KeyBinding Key="Up" Modifiers="Shift" Command="{Binding KeyDownUpArrowAndShiftCommand}"/> 10 <KeyBinding Key="Down" Command="{Binding KeyDownDownArrowCommand}"/> 11 <KeyBinding Key="C" Modifiers="Control" Command="{Binding KeyDownFileCopyCommand}"/> 12 <KeyBinding Key="D" Modifiers="Control" Command="{Binding KeyDownFileDeleteCommand}"/> 13 <KeyBinding Key="O" Modifiers="Control" Command="{Binding KeyDownFileOpenCommand}"/> 14 <KeyBinding Key="T" Modifiers="Control" Command="{Binding KeyDownFileCutOutCommand}"/> 15 </UserControl.InputBindings> 16 17 <Grid Margin="10"> 18 <materialDesign:PackIcon Kind="FolderSearch" Foreground="#eda600" Height="20" Width="20" VerticalAlignment="Bottom"/> 19 <TextBox Grid.Column="1" Text="{Binding TextFullPathCondition, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}"> 20 </TextBox> 21 <TextBlock Grid.Column="2" Text="{Binding FileCount}"/> 22 23 <DataGrid 24 Grid.Row="1" Grid.ColumnSpan="3" 25 ItemsSource="{Binding FileList}" 26 IsReadOnly="{Binding IsReadOnlyFileList}" 27 IsSelected="{Binding IsSelectedGridRow}" 28 SelectedItem="{Binding SelectedFile}" 29 SelectedIndex="{Binding SelectedFileIndex}" 30 b:MouseDoubleClick.Command="{Binding FileListDoubleClickCommand}" 31 SelectionChanged="Selector_OnSelectionChanged" 32 33 AutoGenerateColumns="False" 34 CanUserAddRows="False" 35 CanUserDeleteRows="False" 36 CanUserReorderColumns="False" 37 CanUserSortColumns="True" 38 ClipboardCopyMode="ExcludeHeader" 39 FontSize="10" 40 Height="Auto" 41 SelectionMode="Extended" 42 SelectionUnit="FullRow" 43 44 EnableRowVirtualization="True" 45 EnableColumnVirtualization="true" 46 ScrollViewer.CanContentScroll="True" 47 ScrollViewer.HorizontalScrollBarVisibility="Disabled" 48 ScrollViewer.IsDeferredScrollingEnabled="True" 49 ScrollViewer.PanningMode="VerticalOnly" 50 VirtualizingPanel.CacheLength="10" 51 VirtualizingPanel.CacheLengthUnit="Item" 52 VirtualizingPanel.ScrollUnit="Item" 53 VirtualizingPanel.IsContainerVirtualizable="True" 54 VirtualizingPanel.IsVirtualizing="True" 55 VirtualizingPanel.IsVirtualizingWhenGrouping="True" 56 VirtualizingPanel.VirtualizationMode="Recycling" 57 > 58 <!--キーイベントの割り当て--> 59 <!--UserControlに以下のキーを割り当てるとテキストボックス上で意図した動作をしなくなる為ここで割り当てる--> 60 <DataGrid.InputBindings> 61 <KeyBinding Key="Delete" Command="{Binding KeyDownFileDeleteCommand}"/> 62 <KeyBinding Key="Space" Command="{Binding KeyDownFileOpenCommand}"/> 63 </DataGrid.InputBindings> 64 65 <!--SelectedItemsをVM側で取得できるようにする--> 66 <i:Interaction.Behaviors> 67 <b:SelectedItemsBehavior SelectedItems="{Binding SelectedItems}" /> 68 </i:Interaction.Behaviors> 69 70 <!--各カラムの設定--> 71 <DataGrid.Columns> 72 <DataGridTemplateColumn CanUserResize="False"> 73 <DataGridTemplateColumn.CellTemplate> 74 <DataTemplate> 75 <Image Source="{Binding ImageSource}" /> 76 </DataTemplate> 77 </DataGridTemplateColumn.CellTemplate> 78 </DataGridTemplateColumn> 79 <DataGridTemplateColumn Header="ファイル名" SortMemberPath="FileName"> 80 <DataGridTemplateColumn.CellTemplate> 81 <DataTemplate> 82 <TextBlockText="{Binding FileName}" /> 83 </DataTemplate> 84 </DataGridTemplateColumn.CellTemplate> 85 </DataGridTemplateColumn> 86 <DataGridTemplateColumn Header="フルパス" > 87 <DataGridTemplateColumn.CellTemplate> 88 <DataTemplate> 89 <TextBlock Text="{Binding FullPath}" /> 90 </DataTemplate> 91 </DataGridTemplateColumn.CellTemplate> 92 </DataGridTemplateColumn> 93 <DataGridTemplateColumn Header="更新日時"> 94 <DataGridTemplateColumn.CellTemplate> 95 <DataTemplate> 96 <TextBlock Text="{Binding LastWriteTime}" /> 97 </DataTemplate> 98 </DataGridTemplateColumn.CellTemplate> 99 </DataGridTemplateColumn> 100 </DataGrid.Columns> 101 </DataGrid> 102 </Grid> 103</UserControl>
以下のビヘイビアを使用することで、UserControlで宣言したInputBindingsが優先して実行されます。
C#
1public class InputBindingsBehavior 2{ 3 public static readonly DependencyProperty TakesInputBindingPrecedenceProperty = 4 DependencyProperty.RegisterAttached("TakesInputBindingPrecedence", 5 typeof(bool), 6 typeof(InputBindingsBehavior), 7 new UIPropertyMetadata(false, OnTakesInputBindingPrecedenceChanged)); 8 9 public static bool GetTakesInputBindingPrecedence(UIElement obj) 10 { 11 return (bool)obj.GetValue(TakesInputBindingPrecedenceProperty); 12 } 13 14 public static void SetTakesInputBindingPrecedence(UIElement obj, bool value) 15 { 16 obj.SetValue(TakesInputBindingPrecedenceProperty, value); 17 } 18 19 private static void OnTakesInputBindingPrecedenceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 20 { 21 ((UIElement)d).PreviewKeyDown += new KeyEventHandler(InputBindingsBehavior_PreviewKeyDown); 22 } 23 24 private static void InputBindingsBehavior_PreviewKeyDown(object sender, KeyEventArgs e) 25 { 26 var uielement = (UIElement)sender; 27 28 var foundBinding = uielement.InputBindings 29 .OfType<KeyBinding>() 30 .FirstOrDefault(kb => kb.Key == e.Key && kb.Modifiers == e.KeyboardDevice.Modifiers); 31 32 if (foundBinding != null) 33 { 34 e.Handled = false; 35 if (foundBinding.Command.CanExecute(foundBinding.CommandParameter)) 36 { 37 foundBinding.Command.Execute(foundBinding.CommandParameter); 38 } 39 } 40 } 41}

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/08/15 09:12
2019/08/15 09:35
2019/08/15 09:36