Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public class DgColumnBehavior : Behavior<DataGrid>
- {
- protected ICommand ToggleColumnVisibilityCmd;
- protected DataGrid _AssociatedObject;
- private static VisibilityToBooleanConverter visibilityToBooleanConverter = new VisibilityToBooleanConverter() { HiddenState = Visibility.Hidden };
- protected override void OnAttached()
- {
- this.ToggleColumnVisibilityCmd = new DelegateCommand<DataGridColumn>(ToggleColumnVisibilityCmdExecute);
- this._AssociatedObject = (DataGrid)this.AssociatedObject;
- Observable.FromEventPattern(this._AssociatedObject, "Loaded")
- .Take(1)
- .Subscribe(x => _AssociatedObject_Loaded());
- base.OnAttached();
- }
- void _AssociatedObject_Loaded()
- {
- var columnHeaders = this._AssociatedObject.SafeFindDescendants<DataGridColumnHeader>(); // see second code piece for the SafeFindDescendants extension method
- foreach (var columnHeader in columnHeaders)
- {
- EnsureSeparateContextMenuFor(columnHeader);
- if (columnHeader.ContextMenu.ItemsSource != null)
- {
- // ContextMenu has an ItemsSource, so need to add items to that -
- // ommitted though as irrelevant for example
- }
- else
- {
- // No ItemsSource assigned to the Menu, so we can just add directly
- foreach (var item in CreateMenuItemsFor(columnHeader))
- columnHeader.ContextMenu.Items.Add(item);
- }
- }
- }
- /// Ensures that the columnHeader ...
- /// A) has a ContextMenu, and
- /// B) that is has an individual context menu, i.e. one that isn't shared with any other DataGridColumnHeaders.
- ///
- /// I'm doing that as in practice, I'm adding some further items that are specific to each column, so I can't have a shared context menu
- private void EnsureSeparateContextMenuFor(DataGridColumnHeader columnHeader)
- {
- if (columnHeader.ContextMenu == null)
- {
- columnHeader.ContextMenu = new ContextMenu();
- }
- else
- {
- // clone the existing menu
- // ommitted as irrelevant for example
- }
- }
- /// Creates one menu item for each column of the underlying DataGrid to toggle that column's visibility
- private IEnumerable<FrameworkElement> CreateMenuItemsFor(DataGridColumnHeader columnHeader)
- {
- foreach (var column in _AssociatedObject.Columns)
- {
- var item = new MenuItem();
- item.Header = String.Format("Toggle visibility for {0}", column.Header);
- item.Command = ToggleColumnVisibilityCmd;
- item.CommandParameter = column;
- yield return item;
- }
- }
- // Gets executed when the user clicks on one of the ContextMenu items
- protected void ToggleColumnVisibilityCmdExecute(DataGridColumn column)
- {
- bool isVisible = (column.Visibility == Visibility.Visible);
- Visibility newVisibility = (isVisible) ? Visibility.Hidden : Visibility.Visible;
- column.Visibility = newVisibility;
- }
- }
- public static class Visual_ExtensionMethods
- {
- public static IEnumerable<T> SafeFindDescendants<T>(this Visual @this, Predicate<T> predicate = null) where T : Visual
- {
- if (@this != null)
- {
- int childrenCount = VisualTreeHelper.GetChildrenCount(@this);
- for (int i = 0; i < childrenCount; i++)
- {
- var currentChild = VisualTreeHelper.GetChild(@this, i);
- var typedChild = currentChild as T;
- if (typedChild == null)
- {
- var result = ((Visual)currentChild).SafeFindDescendants<T>(predicate);
- foreach (var r in result)
- yield return r;
- }
- else
- {
- if (predicate == null || predicate(typedChild))
- {
- yield return typedChild;
- }
- }
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement