using System.Collections.Generic; using System.Collections.Specialized; using System.ComponentModel; using System.Reflection; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using Developpez.Dotnet.Collections; namespace Developpez.Dotnet.Windows.Util { /// /// Fournit des propriétés attachées pour définir des colonnes de GridView via un binding sur une collection /// public static class GridViewColumns { /// /// Obtient la valeur de la propriété attachée ColumnsSource pour l'objet spécifié /// /// L'objet pour lequel on veut obtenir la valeur /// La valeur de la propriété attachée ColumnsSource pour cet objet [AttachedPropertyBrowsableForType(typeof(GridView))] public static object GetColumnsSource(DependencyObject obj) { return (object)obj.GetValue(ColumnsSourceProperty); } /// /// Définit la valeur de la propriété attachée ColumnsSource pour l'objet spécifié /// /// L'objet pour lequel on veut obtenir la valeur /// La nouvelle valeur de la propriété attachée ColumnsSource pour cet objet public static void SetColumnsSource(DependencyObject obj, object value) { obj.SetValue(ColumnsSourceProperty, value); } /// /// Identifie la propriété attachée ColumnsSource /// public static readonly DependencyProperty ColumnsSourceProperty = DependencyProperty.RegisterAttached( "ColumnsSource", typeof(object), typeof(GridViewColumns), new UIPropertyMetadata( null, ColumnsSourceChanged)); /// /// Obtient la valeur de la propriété attachée HeaderTextMember pour l'objet spécifié /// /// L'objet pour lequel on veut obtenir la valeur /// La valeur de la propriété attachée HeaderTextMember pour cet objet [AttachedPropertyBrowsableForType(typeof(GridView))] public static string GetHeaderTextMember(DependencyObject obj) { return (string)obj.GetValue(HeaderTextMemberProperty); } /// /// Définit la valeur de la propriété attachée HeaderTextMember pour l'objet spécifié /// /// L'objet pour lequel on veut obtenir la valeur /// La nouvelle valeur de la propriété attachée HeaderTextMember pour cet objet public static void SetHeaderTextMember(DependencyObject obj, string value) { obj.SetValue(HeaderTextMemberProperty, value); } /// /// Identifie la propriété attachée HeaderTextMember /// public static readonly DependencyProperty HeaderTextMemberProperty = DependencyProperty.RegisterAttached("HeaderTextMember", typeof(string), typeof(GridViewColumns), new UIPropertyMetadata(null)); /// /// Obtient la valeur de la propriété attachée DisplayMemberMember pour l'objet spécifié /// /// L'objet pour lequel on veut obtenir la valeur /// La valeur de la propriété attachée DisplayMemberMember pour cet objet [AttachedPropertyBrowsableForType(typeof(GridView))] public static string GetDisplayMemberMember(DependencyObject obj) { return (string)obj.GetValue(DisplayMemberMemberProperty); } /// /// Définit la valeur de la propriété attachée DisplayMemberMember pour l'objet spécifié /// /// L'objet pour lequel on veut obtenir la valeur /// La nouvelle valeur de la propriété attachée DisplayMemberMember pour cet objet public static void SetDisplayMemberMember(DependencyObject obj, string value) { obj.SetValue(DisplayMemberMemberProperty, value); } /// /// Identifie la propriété attachée DisplayMemberMember /// public static readonly DependencyProperty DisplayMemberMemberProperty = DependencyProperty.RegisterAttached("DisplayMemberMember", typeof(string), typeof(GridViewColumns), new UIPropertyMetadata(null)); private static void ColumnsSourceChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) { GridView gridView = obj as GridView; if (gridView != null) { gridView.Columns.Clear(); if (e.OldValue != null) { ICollectionView view = CollectionViewSource.GetDefaultView(e.OldValue); if (view != null) RemoveHandlers(gridView, view); } if (e.NewValue != null) { ICollectionView view = CollectionViewSource.GetDefaultView(e.NewValue); if (view != null) { AddHandlers(gridView, view); CreateColumns(gridView, view); } } } } private static IDictionary> _gridViewsByColumnsSource = new DefaultDictionary>((v) => new List()); private static void AddHandlers(GridView gridView, ICollectionView view) { _gridViewsByColumnsSource[view].Add(gridView); view.CollectionChanged += ColumnsSource_CollectionChanged; } private static void CreateColumns(GridView gridView, ICollectionView view) { foreach (var item in view) { GridViewColumn column = CreateColumn(gridView, item); gridView.Columns.Add(column); } } private static void RemoveHandlers(GridView gridView, ICollectionView view) { view.CollectionChanged -= ColumnsSource_CollectionChanged; _gridViewsByColumnsSource[view].Remove(gridView); } private static void ColumnsSource_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { ICollectionView view = sender as ICollectionView; var gridViews = _gridViewsByColumnsSource[view]; if (gridViews.IsNullOrEmpty()) return; switch (e.Action) { case NotifyCollectionChangedAction.Add: foreach (var gridView in gridViews) { for (int i = 0; i < e.NewItems.Count; i++) { GridViewColumn column = CreateColumn(gridView, e.NewItems[i]); gridView.Columns.Insert(e.NewStartingIndex + i, column); } } break; case NotifyCollectionChangedAction.Move: foreach (var gridView in gridViews) { List columns = new List(); for (int i = 0; i < e.OldItems.Count; i++) { GridViewColumn column = gridView.Columns[e.OldStartingIndex + i]; columns.Add(column); } for (int i = 0; i < e.NewItems.Count; i++) { GridViewColumn column = columns[i]; gridView.Columns.Insert(e.NewStartingIndex + i, column); } } break; case NotifyCollectionChangedAction.Remove: foreach (var gridView in gridViews) { for (int i = 0; i < e.OldItems.Count; i++) { gridView.Columns.RemoveAt(e.OldStartingIndex); } } break; case NotifyCollectionChangedAction.Replace: foreach (var gridView in gridViews) { for (int i = 0; i < e.NewItems.Count; i++) { GridViewColumn column = CreateColumn(gridView, e.NewItems[i]); gridView.Columns[e.NewStartingIndex + i] = column; } } break; case NotifyCollectionChangedAction.Reset: foreach (var gridView in gridViews) { gridView.Columns.Clear(); CreateColumns(gridView, sender as ICollectionView); } break; default: break; } } private static GridViewColumn CreateColumn(GridView gridView, object columnSource) { GridViewColumn column = new GridViewColumn(); string headerTextMember = GetHeaderTextMember(gridView); string displayMemberMember = GetDisplayMemberMember(gridView); if (!headerTextMember.IsNullOrEmpty()) { column.Header = GetPropertyValue(columnSource, headerTextMember); } if (!displayMemberMember.IsNullOrEmpty()) { string propertyName = GetPropertyValue(columnSource, displayMemberMember) as string; column.DisplayMemberBinding = new Binding(propertyName); } return column; } private static object GetPropertyValue(object obj, string propertyName) { if (obj != null) { PropertyInfo prop = obj.GetType().GetProperty(propertyName); if (prop != null) return prop.GetValue(obj, null); } return null; } } }