Unselect DataGridRow in DataGrid

Oggi si è presentato il seguente problema:
Ho usato una griglia per applicare una sorta di filtro su un altro controllo in base alle DataGridRow selezionate; il cliente ha voluto che, cliccando fuori dalle colonne di una DataGrid, tutte le righe selezionate si deselezionassero (eliminando in questo modo il filtro).

L’unico modo navito per farlo è cliccare sulla DataGridRow selezionata tenendo premuto il tasto CTRL.

Ho quindi creato il codice qui sotto.
In pratica cliccando al di fuori delle colonne (parte destra della Griglia) si clicca su un elemento figlio di una DataGridRow ma non su un elemento figlio di una DataGridCell (si può vedere facilmente con WPF Inspector oppure con Snoop).
Testo quindi questa condizione e deseleziono tutto se verificata:

public static class DataGridBehaviors
    {
        public static bool GetUnselectOnClickOutside(DependencyObject obj)
        {
            return (bool)obj.GetValue(UnselectOnClickOutsideProperty);
        }
        
        public static void SetUnselectOnClickOutside(DependencyObject obj, bool value)
        { 
            obj.SetValue(UnselectOnClickOutsideProperty, value); 
        }
        public static readonly DependencyProperty UnselectOnClickOutsideProperty = 
            DependencyProperty.RegisterAttached("UnselectOnClickOutside", typeof(bool), typeof(DataGridBehaviors), 
            new UIPropertyMetadata(false, UnselectOnClickOutsidePropertyChangedCallback));
        
        private static void UnselectOnClickOutsidePropertyChangedCallback(DependencyObject depObj, DependencyPropertyChangedEventArgs eventArgs)
        {
            DataGrid grid = depObj as DataGrid;
            if (depObj != null)
            {
                if ((bool)eventArgs.OldValue == false && (bool)eventArgs.NewValue == true)     
                    grid.MouseLeftButtonUp += AssociatedObjectUnselectOnClickOutside;
                else if 
                    ((bool)eventArgs.OldValue == true && (bool)eventArgs.NewValue == false)      
                    grid.MouseLeftButtonUp -= AssociatedObjectUnselectOnClickOutside;
            }
        }
        
        private static void AssociatedObjectUnselectOnClickOutside(object sender, MouseButtonEventArgs e) 
        {
            DataGrid datagrid = e.Source as DataGrid;
            DependencyObject originalControl = e.OriginalSource as DependencyObject; 
            DataGridCell cell; DataGridRow row;
            if (TryFindParent<DataGridRow>(originalControl, out row) && !TryFindParent<DataGridCell>(originalControl, out cell)) 
            { 
                datagrid.UnselectAll();
            }
        } 
        private static bool TryFindParent<T>(DependencyObject child, out T result) where T : class 
        {
            Contract.Requires(child != null, "child could not be null"); 
            Contract.Ensures(Contract.Result<bool>() == true && Contract.ValueAtReturn<T>(out result) != null
                && result is T, "Result found rule violated"); 
            Contract.Ensures(Contract.Result<bool>() == false && Contract.ValueAtReturn<T>(out result) == null, 
                "Result not found rule violated"); 
            var parent = VisualTreeHelper.GetParent(child); 
            result = parent as T;
            if (result != null)  
                return true; 
            else        
                if (parent != null)
                    return TryFindParent<T>(parent, out result);
                else 
                    return false;
        }
    }

Questo è un behavior applicabile ad ogni griglia tramite AttachedProperty:

<DataGrid ItemsSource=”{Binding}” local:DataGridBehaviors.UnselectOnClickOutside=”True” />

Et voilà! Les jeux sont faits

Pubblicità

, ,

  1. Lascia un commento

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo di WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione /  Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione /  Modifica )

Connessione a %s...

%d blogger hanno fatto clic su Mi Piace per questo: