Search code examples
.netwpfribbon

How can I prevent a wpf ribbon group from fully collapsing without specifying all combinations of size definitions?


How can I prevent a wpf ribbon group from fully collapsing?

I realise there is a RibbonGroup.GroupSizeDefinitions property (it's discussed here: http://msdn.microsoft.com/en-us/library/ff701790.aspx) and if I define a bunch of RibbonGroupSizeDefinition and none with isCollapsed=true it does close to what I want.

Unfortunately I don't want to have to define the size definitions because the buttons shown will vary depending on the users license. eg. one client may get six buttons in a group and one might have four.

So I want it to auto setup the groups but never go into fully collapsed - is this possible?


Solution

  • I have derived Ribbon, RibbonTab and RibbonGroup.

    Instead of rewriting the code of GroupSizeDefinitions, I use reflection to access the GroupSizeDefinitions property.

    public class xxxRibbon : Ribbon
    {
        protected override DependencyObject GetContainerForItemOverride()
        {
            return new xxxRibbonTab();
        }
    }
    
    public class xxxRibbonTab : RibbonTab
    {
        protected override DependencyObject GetContainerForItemOverride()
        {
            return new xxxRibbonGroup();
        }
    }
    
    public class xxxRibbonGroup : RibbonGroup
    {
        public const string PropertyName_IsCollapsable = "IsCollapsable";
        public const string PropertyName_GroupSizeDefinitionsResourceName = "GroupSizeDefinitionsResourceName";
    
        public static readonly DependencyProperty IsCollapsableProperty =
            DependencyProperty.Register(xxxRibbonGroup.PropertyName_IsCollapsable, typeof(bool), typeof(xxxRibbonGroup), new FrameworkPropertyMetadata((bool)true, xxxRibbonGroup.IsCollapsablePropertyChangedCallback));
    
        public static readonly DependencyProperty GroupSizeDefinitionsResourceNameProperty =
            DependencyProperty.Register(xxxRibbonGroup.PropertyName_GroupSizeDefinitionsResourceName, typeof(string), typeof(xxxRibbonGroup), new FrameworkPropertyMetadata((string)null, xxxRibbonGroup.GroupSizeDefinitionsResourceNamePropertyChangedCallback));
    
        public bool IsCollapsable
        {
            get { return (bool)this.GetValue(xxxRibbonGroup.IsCollapsableProperty); }
            set { this.SetValue(xxxRibbonGroup.IsCollapsableProperty, value); }
        }
    
        public string GroupSizeDefinitionsResourceName
        {
            get { return (string)this.GetValue(xxxRibbonGroup.GroupSizeDefinitionsResourceNameProperty); }
            set { this.SetValue(xxxRibbonGroup.GroupSizeDefinitionsResourceNameProperty, value); }
        }
    
        private static void IsCollapsablePropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
        {
            xxxRibbonGroup ribbonGroup = dependencyObject as xxxRibbonGroup;
            if (ribbonGroup == null)
            {
                return;
            }
    
            ribbonGroup.rebuildGroupSizeDefinitions();
        }
    
        private static void GroupSizeDefinitionsResourceNamePropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
        {
            xxxRibbonGroup ribbonGroup = dependencyObject as xxxRibbonGroup;
            if (ribbonGroup == null)
            {
                return;
            }
    
            ribbonGroup.rebuildGroupSizeDefinitions();
        }
    
        protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
        {
            base.OnItemsChanged(e);
    
            this.GroupSizeDefinitions = null;
            this.rebuildGroupSizeDefinitions();
        }
    
        protected override void OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue)
        {
            base.OnItemsSourceChanged(oldValue, newValue);
    
            this.GroupSizeDefinitions = null;
            this.rebuildGroupSizeDefinitions();
        }
    
        private void rebuildGroupSizeDefinitions()
        {
            string resourceName = this.GroupSizeDefinitionsResourceName;
            if (string.IsNullOrEmpty(resourceName) == false)
            {
                object resource = Application.Current.TryFindResource(resourceName);
                if (resource == null)
                {
                    this.GroupSizeDefinitions = null;
                    return;
                }
    
                RibbonGroupSizeDefinitionBaseCollection grsidef = resource as RibbonGroupSizeDefinitionBaseCollection;
                if (grsidef == null)
                {
                    this.GroupSizeDefinitions = null;
                    return;
                }
    
                this.GroupSizeDefinitions = grsidef;
                return;
            }
    
            PropertyInfo[] props = this.GetType().BaseType.GetProperties(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
    
            foreach (PropertyInfo propertyInfo in props)
            {
                if (propertyInfo.Name == "GroupSizeDefinitionsInternal")
                {
                    RibbonGroupSizeDefinitionBaseCollection value = propertyInfo.GetValue(this, BindingFlags.GetProperty | BindingFlags.NonPublic, null, null, null) as RibbonGroupSizeDefinitionBaseCollection;
                    if ((value != null) && (value.Count > 0))
                    {
                        RibbonGroupSizeDefinitionBaseCollection result = new RibbonGroupSizeDefinitionBaseCollection();
                        foreach (RibbonGroupSizeDefinitionBase it in value)
                        {
                            if (this.IsCollapsable == false)
                            {
                                if (it.IsCollapsed == false)
                                {
                                    result.Add(it);
                                }
                            }
                            else
                            {
                                result.Add(it);
                            }
                        }
    
                        result.Freeze();
    
                        this.GroupSizeDefinitions = result;
                        return;
                    }
    
                    return;
                }
            }
    
            Traceur.Assert(false);
        }
    }