RadContextMenu Winforms - How to change hover over colours?

6 Answers 917 Views
ContextMenu
Paul
Top achievements
Rank 1
Iron
Paul asked on 09 Jul 2021, 12:59 PM | edited on 13 Jul 2021, 01:34 PM

Could you tell me if it is possible to change the colour of the item being hovered over within a dynamically created RadContextMenu. I have implemented the code below but it is leaving a "shadow" background system default (see attached) (with 

From init code:

 e.ContextMenu.MouseMove += ContextMenu_MouseMove;


Within Form code:

RadMenuItem lastHoveredItem;
private void  ContextMenu_MouseMove(object sender, MouseEventArgs e)
        {
            RadDropDownMenu menu = (RadDropDownMenu)sender;
            RadMenuItem hoveredItem = menu.ElementTree.GetElementAtPoint(e.Location) as RadMenuItem;
            if (hoveredItem != null)
            {
                if(lastHoveredItem != null && lastHoveredItem != hoveredItem)
                {
                    lastHoveredItem.FillPrimitive.ResetValue(FillPrimitive.BackColorProperty, ValueResetFlags.Local);
                    lastHoveredItem.FillPrimitive.ResetValue(FillPrimitive.ForeColorProperty, ValueResetFlags.Local);
                    lastHoveredItem.ForeColor = Color.Black;
                }

                hoveredItem.FillPrimitive.BackColor = Theming.Current.HighlightedBackground;
                hoveredItem.ForeColor = Theming.Current.HighlightedText1;
                lastHoveredItem = hoveredItem;
            }

        }

The Reset value above is not resetting the ForeColor thus the hard coding back to Black.

 

UPDATE:

The menu items are dynamically created with menu.Items.Clear() called each time. I have created a method which is called once the context menu has been built which runs the code you suggested (looping through the items within the menu) but I am once again getting the "lagged" yellow highlight color showing. It seems to be due to the child/nested context menu entries as I get no issue on single context menus with no children - see newly attached image

6 Answers, 1 is accepted

Sort by
0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 13 Jul 2021, 10:11 AM
Hello, Paul,

If you want to change the fill color when the menu item is hovered, it is appropriate to use the functionality for overriding theme values that the Telerik Presentation Framework offers:

https://docs.telerik.com/devtools/winforms/telerik-presentation-framework/override-theme-settings-at-run-time 

I have prepared a sample code snippet for your reference which result is illustrated in the attached gif file.
        public RadForm1()
        {
            InitializeComponent();

            foreach (RadMenuItem item in this.radContextMenu1.Items)
            {
                item.SetThemeValueOverride(Telerik.WinControls.Primitives.FillPrimitive.BackColorProperty,
                    Color.Red, "RadMenuItem.ContainsMouse.MouseOver.Selected", typeof(Telerik.WinControls.Primitives.FillPrimitive));
                item.SetThemeValueOverride(Telerik.WinControls.Primitives.FillPrimitive.GradientStyleProperty,
                    GradientStyles.Solid, "RadMenuItem.ContainsMouse.MouseOver.Selected", typeof(Telerik.WinControls.Primitives.FillPrimitive)); 
            }
        }
I hope this information helps. If you need any further assistance please don't hesitate to contact me. 

Regards,
Dess | Tech Support Engineer, Principal
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Paul
Top achievements
Rank 1
Iron
commented on 13 Jul 2021, 11:26 AM

Thank you - this solution works perfectly. How would I also change the forecolor? when applying the similar logic as shown in your code it doesn't seem to work: item.SetThemeValueOverride(Telerik.WinControls.Primitives.FillPrimitive.ForeColorProperty,
Color.White, "RadMenuItem.ContainsMouse.MouseOver.Selected", typeof(Telerik.WinControls.Primitives.FillPrimitive));
0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 13 Jul 2021, 11:40 AM

Hello, Paul,

You can change the forecolor in a similar way, however it wouldn't be applied to the FillPrimitive element:

 

        public RadForm1()
        {
            InitializeComponent();

            foreach (RadMenuItem item in this.radContextMenu1.Items)
            {
                item.SetThemeValueOverride(Telerik.WinControls.Primitives.FillPrimitive.BackColorProperty,
                    Color.Red, "RadMenuItem.ContainsMouse.MouseOver.Selected", typeof(Telerik.WinControls.Primitives.FillPrimitive));
                item.SetThemeValueOverride(Telerik.WinControls.Primitives.FillPrimitive.GradientStyleProperty,
                    GradientStyles.Solid, "RadMenuItem.ContainsMouse.MouseOver.Selected", typeof(Telerik.WinControls.Primitives.FillPrimitive)); 

                 item.SetThemeValueOverride(LightVisualElement.ForeColorProperty,
                    Color.Lime, "RadMenuItem.ContainsMouse.MouseOver.Selected" );
            }
        }

Should you have further questions please let me know.

Regards,
Dess | Tech Support Engineer, Principal
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

Paul
Top achievements
Rank 1
Iron
commented on 13 Jul 2021, 01:14 PM

Thanks - I have added this to my solution though I still have an issue - I have updated the question
0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 14 Jul 2021, 08:13 AM

Hello, Paul,

The previously provided solution iterates only the RadMenuItems at the top level. If you want the nested menu items to be affected as well, it is necessary to iterate the items recursively. Thus, the child menu items will have the same colors:

        public RadForm1()
        {
            InitializeComponent();

            ChangeHoverStyle(this.radContextMenu1.Items); 
        }

        private void ChangeHoverStyle(RadItemOwnerCollection items)
        {
            foreach (RadMenuItem item in items)
            {
                item.SetThemeValueOverride(Telerik.WinControls.Primitives.FillPrimitive.BackColorProperty,
                    Color.Red, "RadMenuItem.ContainsMouse.MouseOver.Selected", typeof(Telerik.WinControls.Primitives.FillPrimitive));
                item.SetThemeValueOverride(Telerik.WinControls.Primitives.FillPrimitive.GradientStyleProperty,
                    GradientStyles.Solid, "RadMenuItem.ContainsMouse.MouseOver.Selected", typeof(Telerik.WinControls.Primitives.FillPrimitive));

                item.SetThemeValueOverride(LightVisualElement.ForeColorProperty,
                   Color.Lime, "RadMenuItem.ContainsMouse.MouseOver.Selected");

                if (item.Items.Count>0)
                {
                    ChangeHoverStyle(item.Items);
                }
            }
        }

You can also apply a different color for the "Selected" state if you need to indicate in a different color the parent menu item:

        private void ChangeHoverStyle(RadItemOwnerCollection items)
        {
            foreach (RadMenuItem item in items)
            {
                item.SetThemeValueOverride(Telerik.WinControls.Primitives.FillPrimitive.BackColorProperty,
                    Color.Red, "RadMenuItem.ContainsMouse.MouseOver.Selected", typeof(Telerik.WinControls.Primitives.FillPrimitive));
                item.SetThemeValueOverride(Telerik.WinControls.Primitives.FillPrimitive.GradientStyleProperty,
                    GradientStyles.Solid, "RadMenuItem.ContainsMouse.MouseOver.Selected", typeof(Telerik.WinControls.Primitives.FillPrimitive));
                item.SetThemeValueOverride(LightVisualElement.ForeColorProperty,
                   Color.Lime, "RadMenuItem.ContainsMouse.MouseOver.Selected");

                item.SetThemeValueOverride(Telerik.WinControls.Primitives.FillPrimitive.BackColorProperty,
                    Color.Red, "Selected", typeof(Telerik.WinControls.Primitives.FillPrimitive));
                item.SetThemeValueOverride(Telerik.WinControls.Primitives.FillPrimitive.GradientStyleProperty,
                    GradientStyles.Solid, "Selected", typeof(Telerik.WinControls.Primitives.FillPrimitive));

                if (item.Items.Count>0)
                {
                    ChangeHoverStyle(item.Items);
                }
            }
        }

Should you have further questions please let me know.

Regards,
Dess | Tech Support Engineer, Principal
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Paul
Top achievements
Rank 1
Iron
commented on 14 Jul 2021, 09:21 AM

Thank you again for your considered response. The code now produces almost exactly what I need - however there is still the problem of the original yellow/cream background appearing as a latent shadow which I produced a GIF of on my original ticket. Do you have any thoughts on this?
0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 14 Jul 2021, 10:15 AM
Hello, Paul,

When the drop down menu with the child items remains opened while another item is hovered, there is a highlight style coming from other element states. The attached OpenedDropDown.gif file illustrates the behavior on my end with the Fluent theme.

You can override the theme settings for the "IsPopupShown" state as well:

        private void ChangeHoverStyle(RadItemOwnerCollection items)
        {
            foreach (RadMenuItem item in items)
            {
                 item.SetThemeValueOverride(Telerik.WinControls.Primitives.FillPrimitive.BackColorProperty,
                    Color.Red, "IsPopupShown", typeof(Telerik.WinControls.Primitives.FillPrimitive));
                item.SetThemeValueOverride(Telerik.WinControls.Primitives.FillPrimitive.GradientStyleProperty,
                    GradientStyles.Solid, "IsPopupShown", typeof(Telerik.WinControls.Primitives.FillPrimitive));

                item.SetThemeValueOverride(Telerik.WinControls.Primitives.FillPrimitive.BackColorProperty,
                    Color.Red, "RadMenuItem.ContainsMouse.MouseOver.Selected", typeof(Telerik.WinControls.Primitives.FillPrimitive));
                item.SetThemeValueOverride(Telerik.WinControls.Primitives.FillPrimitive.GradientStyleProperty,
                    GradientStyles.Solid, "RadMenuItem.ContainsMouse.MouseOver.Selected", typeof(Telerik.WinControls.Primitives.FillPrimitive));
                item.SetThemeValueOverride(LightVisualElement.ForeColorProperty,
                   Color.Lime, "RadMenuItem.ContainsMouse.MouseOver.Selected");

                item.SetThemeValueOverride(Telerik.WinControls.Primitives.FillPrimitive.BackColorProperty,
                    Color.Red, "Selected", typeof(Telerik.WinControls.Primitives.FillPrimitive));
                item.SetThemeValueOverride(Telerik.WinControls.Primitives.FillPrimitive.GradientStyleProperty,
                    GradientStyles.Solid, "Selected", typeof(Telerik.WinControls.Primitives.FillPrimitive));

                if (item.Items.Count>0)
                {
                    ChangeHoverStyle(item.Items);
                }
            }
        }

I have attached my sample project for your reference. It is possible to inspect what are the element states for a specific element/item in Visual Style Builder:

Thus, you can extend the previous sample code snippet and provide additional customizations to the style settings.

If you need any further assistance please don't hesitate to contact me. 

Regards,
Dess | Tech Support Engineer, Principal
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

0
Paul
Top achievements
Rank 1
Iron
answered on 15 Jul 2021, 03:37 PM | edited on 06 Aug 2021, 10:25 AM

So grateful for your time and help. I finally achieved the effect I was after using the code in the final reply. Thanks :)

 

UPDATE:

I have now added images to the context menu items however I when they are NOT hovered over they are black outline icons, when the ARE hovered (as the background colour is dark) I would like to change the icons to a White outline icon. I cannot see how to do this with this implementation as I cannot directly access the RadMenuItem. My thought was to use the MouseEnter and MouseLeave events - but it seems the RadMenuItem during the mouse leave event has a NULL image.tag (which I use to store the image name). Would you have any guidance on this ?

 

I suspect also that when following children menu items the parent will trigger the mouse leave event which will not look great

0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 09 Aug 2021, 01:45 PM

Hello, Paul,

Handling the MouseEnter and MouseLeave events are appropriate for applying different images to the desired menu item. I have prepared a sample code snippet for your reference which result is illustrated in the gif file:

        public RadForm1()
        {
            InitializeComponent();

            this.radMenuItem2.MouseEnter += RadMenuItem2_MouseEnter;
            this.radMenuItem2.MouseLeave += RadMenuItem2_MouseLeave;
            this.radMenuItem2.Image = Properties.Resources.folder;

            ChangeHoverStyle(this.radContextMenu1.Items); 
        }

        private void RadMenuItem2_MouseLeave(object sender, EventArgs e)
        {
            RadMenuItem item = sender as RadMenuItem;
            item.Image = Properties.Resources.folder;
        }

        private void RadMenuItem2_MouseEnter(object sender, EventArgs e)
        {
            RadMenuItem item = sender as RadMenuItem;
            item.Image = Properties.Resources.edit;
        }

I believe that you will find the sample project helpful for achieving your goal.

Regards,
Dess | Tech Support Engineer, Principal
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

Paul
Top achievements
Rank 1
Iron
commented on 16 Aug 2021, 02:39 PM

Got it - thanks :)
Tags
ContextMenu
Asked by
Paul
Top achievements
Rank 1
Iron
Answers by
Dess | Tech Support Engineer, Principal
Telerik team
Paul
Top achievements
Rank 1
Iron
Share this question
or