none
DataGridのEndキー入力でCtrl+Endキーの場合と同等の操作にしたい RRS feed

  • 質問

  • DataGridのキー操作について質問があります。

    以下のようなDataGridのサンプルコードを実装した場合、
    DataGridでは、「Ctrl+End」キーを押すと、最後の行が選択状態になります。それに対して「End」キーだけでは、その行の最後のCellにフォーカスが当たります(選択している行は変わりません)。

    これについて、「End」キーだけで、「Ctrl+End」キーを押した場合と同等の動きにしたいと思いますが、うまく実装することができません。良い実装方法についてお教えいただけますと幸いです。

    よろしくお願いします。

    ----

    <Window x:Class="TestApp.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:TestApp"
            mc:Ignorable="d"
            Title="MainWindow" Height="350" Width="525">
        <Window.DataContext>
            <local:ViewModel/>
        </Window.DataContext>
        <DataGrid ItemsSource="{Binding ListItems}" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn  Header="Name" Binding="{Binding Name}"/>
            </DataGrid.Columns>
        </DataGrid>
    </Window>
        public class ViewModel
        {
            public ViewModel()
            {
                for(int i=0; i< 10; i++)
                {
                    ListItems.Add(new TestClass() {Name="A"+i });
                }
            }
    
            public List<TestClass> ListItems { get; } = new List<TestClass>();
        }
    
        public class TestClass
        {
            public string Name { get; set; }
        }

    • 編集済み yy10 2020年4月10日 5:47
    2020年4月10日 5:46

回答

  • こんな

    <DataGrid  ItemsSource="{Binding Path=ListItems}" AutoGenerateColumns="False" 
                SelectionUnit="Cell" CanUserAddRows="true">
    
        <DataGrid.CommandBindings>
            <CommandBinding Command="{x:Static EditingCommands.SelectToDocumentEnd}"
                            CanExecute="CommandBinding_CanExecute" 
                            Executed="CommandBinding_Executed" />
        </DataGrid.CommandBindings>
            
        <DataGrid.InputBindings>
            <KeyBinding Key="End" Command="{x:Static EditingCommands.SelectToDocumentEnd}"  />
        </DataGrid.InputBindings>
            
        <DataGrid.Columns>
            <DataGridTextColumn  Binding="{Binding Path=Name}"/>
            <DataGridTextColumn  Binding="{Binding Path=Name}"/>
            <DataGridTextColumn  Binding="{Binding Path=Name}"/>
        </DataGrid.Columns>
    </DataGrid>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    
        private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
            e.Handled = true;
        }
    
        private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            var dg = (DataGrid)sender;
            var current = dg.CurrentCell;
            var request = new TraversalRequest(FocusNavigationDirection.Last);
    
            dg.MoveFocus(request);
    
            if (current != dg.CurrentCell)
            {
                switch (dg.SelectionUnit)
                {
                case DataGridSelectionUnit.Cell:
                case DataGridSelectionUnit.CellOrRowHeader:
                    dg.SelectedCells.Clear();
                    dg.SelectedCells.Add(dg.CurrentCell);
                    break;
                case DataGridSelectionUnit.FullRow:
                    dg.SelectedIndex = dg.Items.Count - 1;
                    break;
                default:
                    break;
                }
    
                e.Handled = true;
            }
        }
    }


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク yy10 2020年4月13日 1:55
    2020年4月10日 9:25

すべての返信

  • こんな

    <DataGrid  ItemsSource="{Binding Path=ListItems}" AutoGenerateColumns="False" 
                SelectionUnit="Cell" CanUserAddRows="true">
    
        <DataGrid.CommandBindings>
            <CommandBinding Command="{x:Static EditingCommands.SelectToDocumentEnd}"
                            CanExecute="CommandBinding_CanExecute" 
                            Executed="CommandBinding_Executed" />
        </DataGrid.CommandBindings>
            
        <DataGrid.InputBindings>
            <KeyBinding Key="End" Command="{x:Static EditingCommands.SelectToDocumentEnd}"  />
        </DataGrid.InputBindings>
            
        <DataGrid.Columns>
            <DataGridTextColumn  Binding="{Binding Path=Name}"/>
            <DataGridTextColumn  Binding="{Binding Path=Name}"/>
            <DataGridTextColumn  Binding="{Binding Path=Name}"/>
        </DataGrid.Columns>
    </DataGrid>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    
        private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
            e.Handled = true;
        }
    
        private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            var dg = (DataGrid)sender;
            var current = dg.CurrentCell;
            var request = new TraversalRequest(FocusNavigationDirection.Last);
    
            dg.MoveFocus(request);
    
            if (current != dg.CurrentCell)
            {
                switch (dg.SelectionUnit)
                {
                case DataGridSelectionUnit.Cell:
                case DataGridSelectionUnit.CellOrRowHeader:
                    dg.SelectedCells.Clear();
                    dg.SelectedCells.Add(dg.CurrentCell);
                    break;
                case DataGridSelectionUnit.FullRow:
                    dg.SelectedIndex = dg.Items.Count - 1;
                    break;
                default:
                    break;
                }
    
                e.Handled = true;
            }
        }
    }


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク yy10 2020年4月13日 1:55
    2020年4月10日 9:25
  • gekka様

    とても参考になります。ありがとうございます。

    2020年4月13日 1:55