Archivio per giugno 2011
Multi-touch in WPF 4
Pubblicato un articolo dove vengono mostrare le caratteristiche multitouch di WPF4.
Sicuramente il dispositivi Touch saranno il futuro per quanto riguarda l’interfacciamento uomo-macchina, quindi cominciare fin da subito a capire come funziona e conoscere gli strumenti a disposizione è indubbiamente un vantaggio.
Buona lettura: http://www.wpfitalia.it/Contenuti/VediArticoli/tabid/83/ArticleId/46/Il-supporto-al-multi-touch-in-WPF-4.aspx
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