bugfix> c# > 投稿

かなりの数の列があるデータグリッドがあります。通常、ユーザーはTabキーを押して、DataGridセル内のコントロールを切り替えることができます。データグリッドセルはIsTabStop = falseに設定されているため、セル自体へのフォーカスはスキップされ、実際のコントロールにフォーカスが移るまでそのまま通過します。

ユーザーがEnterキーを押した場合、同じ列内で作業する必要があるため、これは機能しないようです。 DataGridはCOLUMNの次のセルにフォーカスを渡しますが、IsTabStop設定も無視するため、内部のコントロールではなくセル自体にフォーカスを与えるだけです。

これを修正する方法のアイデア。

短い例

<DataGrid AutoGenerateColumns="False" Name="grid1" >
    <DataGrid.Resources>
        <Style TargetType="{x:Type Border}" x:Key="coloredBorder">
            <Setter Property="Background" Value="Yellow"/>
        </Style>
        <Style TargetType="DataGridCell">
            <Setter Property="IsTabStop" Value="False"/>
        </Style>
    </DataGrid.Resources>
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding A, Mode=OneWay}" Header="A"/>
        <DataGridTemplateColumn Header="B">
            <DataGridTemplateColumn.CellStyle>
                <Style TargetType="{x:Type DataGridCell}" BasedOn="{StaticResource {x:Type DataGridCell}}">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type DataGridCell}">
                                <Grid>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="Auto"/>
                                        <ColumnDefinition/>
                                    </Grid.ColumnDefinitions>
                                    <Border BorderBrush="Black" BorderThickness="0,0,1,0" Width="20" Height="20" Style="{DynamicResource coloredBorder}"/>
                                    <ComboBox Grid.Column="1" SelectedItem="{Binding A, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
                                                ItemsSource="{Binding MenuItems, ElementName=window}"></ComboBox>
                                </Grid>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </DataGridTemplateColumn.CellStyle>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

また、このためにサンプルのWPFアプリを追加しましたここに。再現するには、コンボボックスのいずれかをクリックして、フォーカスを与えます。 Presタブを押すと、次のコンボボックスが通常どおりフォーカスされていることがわかります。複数のコンボボックス列を追加すると、右側のコンボボックスにフォーカスが移動します。

ただし、Enterキーを押すと、フォーカスは下のセルに移動しますが、セルをスキップしてセルの内容に移動することはありません。代わりに、セルが強調表示されます。 そのようです:

回答 1 件
  • MSDNで得た返信に基づいて:

    添付プロパティを作成することでこれを解決しました:

    using System.Windows;
    using System.Windows.Input;
    namespace GridTabbing
    {
        public class EnterKeySample
        {
            public static bool GetIsEnabled(DependencyObject obj)
            {
                return (bool)obj.GetValue(IsEnabledProperty);
            }
            public static void SetIsEnabled(DependencyObject obj, bool value)
            {
                obj.SetValue(IsEnabledProperty, value);
            }
            static void ue_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
            {
                var ue = e.OriginalSource as FrameworkElement;
                if (e.Key == Key.Enter)
                {
                    e.Handled = true;
                    ue.MoveFocus(new TraversalRequest(FocusNavigationDirection.Down));
                }
            }
            private static void ue_Unloaded(object sender, RoutedEventArgs e)
            {
                var ue = sender as FrameworkElement;
                if (ue == null) return;
                ue.Unloaded -= ue_Unloaded;
                ue.PreviewKeyDown -= ue_PreviewKeyDown;
            }
            public static readonly DependencyProperty IsEnabledProperty =
                DependencyProperty.RegisterAttached("IsEnabled", typeof(bool),
                typeof(EnterKeySample), new UIPropertyMetadata(false, IsEnabledChanged));
            static void IsEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                var ue = d as FrameworkElement;
                if (ue == null) return;
                if ((bool)e.NewValue)
                {
                    ue.Unloaded += ue_Unloaded;
                    ue.PreviewKeyDown += ue_PreviewKeyDown;
                }
                else
                {
                    ue.PreviewKeyDown -= ue_PreviewKeyDown;
                }
            }
        }
    }
    
    

    奇妙なことは、これが行っている唯一のことは、ユーザーがEnterキーを押したときにフォーカスをDOWNに渡すようWPFに伝えることです。

あなたの答え