Your Privacy Matters: We use our own and third-party cookies to improve your experience on our website. By continuing to use the website we understand that you accept their use. Cookie Policy
1150
Is there something wrong with my approach of column menus?
posted

Hi,

I'm using the following approach for adding field chooser context menus for column headers:

public class ExtendedGrid : XamDataGrid, IColumnLayout
{
    protected override void OnFieldLayoutInitialized(FieldLayoutInitializedEventArgs args)
    {
        base.OnFieldLayoutInitialized(args);

        this.SetupColumnMenus();

        foreach (FieldLayout colLayout in this.FieldLayouts)
        {
            colLayout.Fields.CollectionChanged += this.OnFieldsChanged;
        }
    }

    private void OnFieldsChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        this.SetupColumnMenus();
    }

    private void SetupColumnMenus()
    {
        Style originalStyle = this.FindResource(typeof(LabelPresenter)) as Style;

        foreach (FieldLayout colLayout in this.FieldLayouts)
        {
            ContextMenu columnSubMenu = new ContextMenu();

            Style headerPresenterStyle = new Style(typeof(DataRecordPresenter));
            Trigger isHeaderRecordTrigger = new Trigger { Property = DataRecordPresenter.IsHeaderRecordProperty, Value = true };
            headerPresenterStyle.Triggers.Add(isHeaderRecordTrigger);
            isHeaderRecordTrigger.Setters.Add(new Setter(ContextMenuProperty, columnSubMenu));
            colLayout.Settings.DataRecordPresenterStyle = headerPresenterStyle;

            Style newSubStyle = new Style(typeof(LabelPresenter));
            newSubStyle.BasedOn = originalStyle;
            newSubStyle.Setters.Add(new Setter(ContextMenuProperty, columnSubMenu));

            foreach (Field col in colLayout.Fields.OrderBy(x => x.Label))
            {
                SetupColumnContextMenu(newSubStyle, columnSubMenu, col);
            }
        }
    }

    private static void SetupColumnContextMenu(Style styleWithContextMenu, ItemsControl columnMenu, Field col)
    {
        if (col == null || col.Settings == null)
        {
            return;
        }

        if (!col.HasLabel)
        {
            return;
        }

        col.Settings.LabelPresenterStyle = styleWithContextMenu;

        MenuItem item = new MenuItem() { Header = col.Label };            
        item.IsChecked = col.Visibility == Visibility.Visible;
        BindingOperations.SetBinding(col, Field.VisibilityProperty, new Binding() { Source = item, Path = new PropertyPath(MenuItem.IsCheckedProperty), Converter = new BooleanToVisibilityConverter(), Mode = BindingMode.OneWay });
        item.IsCheckable = true;
        columnMenu.Items.Add(item);
    }
}

This approch works nicely, however, one issue surfaced and I don't know why. Sometimes, the context menu just stops working. When you right click a column header, nothing happens. It starts working again if you expand a collapsed record and make OnFieldLayoutInitialized() fire again when a child field layout is loaded. So it seems to me that the grid loses track of the DataRecordPresenterStyle and LabelPresenterStyle. But for what reason? Is there some kind "recycling" / container generation of header controls taking place that causes such issues? Or anything else I am missing?

Regards,

Florian

Parents Reply Children