How can I override DataGrid selection behavior?

前端 未结 3 1829
不思量自难忘°
不思量自难忘° 2021-01-22 06:27

I would like to modify the selection behavior of the DataGrid in the following way. Normally when you have multiple rows selected, and then you click one of the items already se

3条回答
  •  情书的邮戳
    2021-01-22 06:42

    The only thing I could come up with feels like a big hack, so better don't use it as is. But it might be a starting point for finding your own solution.

    Basic ideas:

    • Execute some event handlers even on handled events with EventManager.RegisterClassHandler. This needs some refinement or you end up messing with all cells in the whole application
    • Register for cell selection restore when left mouse click on selected cell without modifiers
    • Consider drag & drop only after left mouse click on selected cell (otherwise the user experience becomes REALLY strange for this combination of requirements)
    • Restore selected cells if previously registered and cells are unselected
    • Remove cell selection restore registration after restoring or when mouse does other things (mouse up or mouse move)

    Customized data grid code:

    public class MyDataGrid : DataGrid
    {
        static MyDataGrid()
        {
            EventManager.RegisterClassHandler(typeof(DataGridCell), UIElement.PreviewMouseLeftButtonDownEvent, new MouseButtonEventHandler(PreviewMouseLeftButtonDownHandler));
            EventManager.RegisterClassHandler(typeof(DataGridCell), UIElement.MouseLeftButtonUpEvent, new MouseButtonEventHandler(MouseLeftButtonUpHandler), true);
            EventManager.RegisterClassHandler(typeof(DataGridCell), UIElement.MouseMoveEvent, new MouseEventHandler(MouseMoveHandler), true);
        }
    
        private static bool restoreNextCells = false;
        private static bool isSelectedCell = false;
        private static void PreviewMouseLeftButtonDownHandler(object sender, MouseButtonEventArgs e)
        {
            var cell = sender as DataGridCell;
            isSelectedCell = cell.IsSelected;
            restoreNextCells = cell.IsSelected && Keyboard.Modifiers == ModifierKeys.None;
        }
        private static void MouseMoveHandler(object sender, MouseEventArgs e)
        {
            var cell = sender as DataGridCell;
            if (isSelectedCell && e.LeftButton == MouseButtonState.Pressed && cell.IsSelected && Keyboard.Modifiers == ModifierKeys.None)
            {
                DragDrop.DoDragDrop(cell, new ObjectDataProvider(), DragDropEffects.All);
            }
            restoreNextCells = false;
            isSelectedCell = false;
        }
    
        private static void MouseLeftButtonUpHandler(object sender, MouseButtonEventArgs e)
        {
            restoreNextCells = false;
            isSelectedCell = false;
        }
        protected override void OnSelectedCellsChanged(SelectedCellsChangedEventArgs e)
        {
            if (restoreNextCells && e.RemovedCells.Count > 0)
            {
                foreach (DataGridCellInfo item in e.RemovedCells)
                {
                    SelectedCells.Add(item);
                }
                restoreNextCells = false;
            }
            base.OnSelectedCellsChanged(e);
        }
    }
    

    Use with multi cell selection.

    
    

    Hope I didn't leave out any important part in my explanation... ask if anything is unclear.

提交回复
热议问题