none
DataGrid Verhalten beim selektieren von Rows RRS feed

  • Frage

  • Hallo zusammen,

    ich verwende grade das DataGrid und stoße wieder einmal an Grenzen die zu überwinden mir nicht so leicht von der Hand geht. Es scheint so zu sein das Rows immer beim MouseLeftButtonDown-Event selektiert werden. Das ist im Zusammenhang mit drag'n'drop allerdings äußerst unschön, Da, wenn der User mehrere Rows ausgewählt hat und diese nun per d'n'd ziehen möchte, die Selektion wieder aufgehoben wird. Im Windows-Explorer, den ich hier einmal ans Referenz für das richtige Verhalten angeben möchte ist das Verhalten von 3 Faktoren abhängig.

    1. Shift-Key
    2. Ctrl-Key
    3. Ist Row unter Cursor Selectiert

    Daraus ergibt sich folgende Tabelle:

    Shift Ctrl Selected Event Selection Focus
    Pressed Pressed Ja NA
    Pressed Pressed Nein MouseLeftButtonDown Die Selektion wird vom der Zeile die den Fokus hat zu der Zeile unter dem Cursor erweitert Focus wird auf Zeile unter dem Cursor gesetzt
    Pressed Released Ja MouseLeftButtonDown Die Selektion wird vom der Zeile die den Fokus hat zu der Zeile unter dem Cursor erweitert Focus bleibt auf der ursprünglichen Zeile
    Pressed Released Nein MouseLeftButtonDown Die Selektion wird vom der Zeile die den Fokus hat zu der Zeile unter dem Cursor erweitert Focus bleibt auf der ursprünglichen Zeile
    Released Pressed Ja MouseLeftButtoUp Zeile unter dem Cursor wird deselektiert  Focus wird auf Zeile unter dem Cursor gesetzt
    Released Pressed Nein MouseLeftButtoUp Zeile unter dem Cursor wird deselektiert  Focus wird auf Zeile unter dem Cursor gesetzt
    Released Released Ja MouseLeftButtoUp Die ursprüngliche Selektion wird aufgehoben und die Zeile unter dem Cursor wird Selectiert Focus wird auf Zeile unter dem Cursor gesetzt
    Released Released Nein MouseLeftButtonDown Die ursprüngliche Selektion wird aufgehoben und die Zeile unter dem Cursor wird Selectiert Focus wird auf Zeile unter dem Cursor gesetzt

    Hat jemand sowas schon einmal umgesetzt? Oder hat jemand eine Idee wo ich einhacken muss um das hizukriegen?


    Gruß
    Rene




    Dienstag, 6. November 2012 12:00

Antworten

  • Hallo Zusammen,

    falls es jemanden interessiert, habe ich hier eine Lösung für das Problem. Ist nicht ganz perfekt, da das DataGrid nicht zwischen SeletedItem/SelectedRow und FocusedItem/FocusedRow unterscheidet, aber es reicht für 99%.

        class test
        {
            private DataGrid _dataGrid;
            public static T GetVisualChild<T>(
                DependencyObject parent)
                where T : Visual
            {
                T child = default(T);
                int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
                for (int i = 0; i < numVisuals; i++)
                {
                    Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
                    child = v as T;
                    if (child == null)
                    {
                        child = GetVisualChild<T>(v);
                    }
                    if (child != null)
                    {
                        break;
                    }
                }
                return child;
            }         public static T GetVisualParent<T>(DependencyObject element) where T : DependencyObject
            {
                DependencyObject parent = element;
                while (parent != null)
                {
                    T tmpParent = parent as T;
                    if (tmpParent != null)
                    {
                        return tmpParent;
                    }
                    parent = VisualTreeHelper.GetParent(parent) as UIElement;
                }
                return null;
            } private bool IsRowSelected( DependencyObject dependencyObject) { var row = GetVisualParent<DataGridRow>(dependencyObject); if (row != null) { return _dataGrid.SelectedItems.Contains(row.DataContext); } return false; } protected bool IsCtrlKeyDown() { return Keyboard.IsKeyDown(Key.RightCtrl) || Keyboard.IsKeyDown(Key.LeftCtrl); } protected bool IsShiftKeyDown() { return Keyboard.IsKeyDown(Key.RightShift) || Keyboard.IsKeyDown(Key.LeftShift); } protected bool IsShiftKeyUp() { return Keyboard.IsKeyUp(Key.RightShift) && Keyboard.IsKeyUp(Key.LeftShift); } protected bool IsCtrlKeyUp() { return Keyboard.IsKeyUp(Key.RightCtrl) && Keyboard.IsKeyUp(Key.LeftCtrl); } public void CreateDataGrid() { _dataGrid = new DataGrid(); //... _dataGrid.PreviewMouseLeftButtonDown += (sender, args) => { if (IsShiftKeyDown()) { if (IsCtrlKeyDown()) { //base.OnPreviewMouseLeftButtonDown(args); } else { var row = GetVisualParent<DataGridRow>(args.OriginalSource as DependencyObject); if (row != null) { var lowerBounds = Math.Min(_dataGrid.SelectedIndex, row.GetIndex()); var upperBounds = Math.Max(_dataGrid.SelectedIndex, row.GetIndex()); _dataGrid.SelectedItems.Clear(); for (int i = lowerBounds; i <= upperBounds; i++) { var item = _dataGrid.Items.GetItemAt(i); _dataGrid.SelectedItems.Add(item); } } } } else { if (IsCtrlKeyUp() && !IsRowSelected(args.OriginalSource as DependencyObject)) { var row = GetVisualParent<DataGridRow>(args.OriginalSource as DependencyObject); if (row != null) { _dataGrid.SelectedItems.Clear(); _dataGrid.SelectedItem = row.DataContext; } } else { var row = GetVisualChild<DataGridRow>(args.OriginalSource as DependencyObject); var presenter = GetVisualChild<DataGridCellsPresenter>(row); var cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromItem(row.DataContext); cell.Focus(); args.Handled = true; } } }; _dataGrid.PreviewMouseLeftButtonUp += (sender, args) => { if (IsShiftKeyUp()) { var row = GetVisualParent<DataGridRow>(args.OriginalSource as DependencyObject); if (row != null) { if (IsCtrlKeyDown()) { if (IsRowSelected(args.OriginalSource as DependencyObject)) { _dataGrid.SelectedItems.Remove(row.DataContext); } else { _dataGrid.SelectedItems.Add(row.DataContext); } } else { if (IsRowSelected(args.OriginalSource as DependencyObject)) { _dataGrid.SelectedItems.Clear(); _dataGrid.SelectedItem = row.DataContext; } } } } }; } }

    Gruß
    Rene


    • Als Antwort markiert Rene Niediek Mittwoch, 7. November 2012 09:43
    • Bearbeitet Rene Niediek Mittwoch, 7. November 2012 13:40 Fehler in Code
    Mittwoch, 7. November 2012 09:41