Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 4084
  • Last Modified:

C# windows Form Application menuitem Hover

Using Microsoft.net 2008 , Framework 3.5:

Is there a way to remove the annoying blue highlight that appears on a menuitem when the mouse moves over it?

Is there a way to change the blue highlight to another color?

is there a way to have a menuitem disable without it being grayed out?

Thanks,
0
asukhu
Asked:
asukhu
  • 6
  • 5
1 Solution
 
chrisbrayCommented:
Hi asukhu

I am not sure you have thought through the proposed changes carefully enough...

The highlight is there for a reason - it indicates which menu item the mouse is currently over and thereby prevents accidental clicking of the wrong menu item.  You should therefore not remove it is it is likely to lead to support problems with your users!

You can disable a menu item without graying it out, but how will the user know that it is disabled?  This is likely to lead to users trying to click a disabled menu item and thinking your program is broken, or not clicking an important item because they think it does not work.

However, if you really want to do this you can do it by simply removing and replacing the handler:

// Remove the handler
 this.newToolStripMenuItem.Click -= new System.EventHandler(this.newToolStripMenuItem_Click);

// Put the handler back
 this.newToolStripMenuItem.Click += new System.EventHandler(this.newToolStripMenuItem_Click);

In addition to the obvious limitations to your application you are proposing, if you implement them the application will no longer meet the Windows standards and will therefore be seen as of less value than compliant applications - and because it does not work the way users would expect it will be much more difficult for them to work with.  I recommend you rethink the proposal.

Chris Bray
0
 
asukhuAuthor Commented:
I am not trying to use a menu bar as a actual "menu bar" I am using it to display data and information.

I tried removing the handler but that doesn't work:

// Remove the handler
this.newToolStripMenuItem.Click -= new System.EventHandler(this.newToolStripMenuItem_Click);

// Put the handler back
this.newToolStripMenuItem.Click += new System.EventHandler(this.newToolStripMenuItem_Click);

how can we disable a button but let it show that it is enabled?
0
 
chrisbrayCommented:
Hi asukhu:

> I am not trying to use a menu bar as a actual "menu bar" I am using it to display data and > information.

Then in your shoes I would rethink the delivery method.  A menu is designed to have a specific function and if you are not using it as a menu it is a bit like using a car as a cupboard - it will work, but is a pointless and expensive waste of the extra features that are not needed.

> I tried removing the handler but that doesn't work:

If you have actually removed the handler it cannot do anything.  I therefore suspect an error in your code - think of it logically, and you will realise that if there is no handler nothing can happen when you click a menu item!

Chris Bray  
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
chrisbrayCommented:
Hi asukhu:

Attached is the code for a simple project that demonstrates the method for removing the handler, and of course it actually works!   Build and run the app, click the Test menu item and a message box is displayer.  Click the Remove Handler button, and you will find that the menu item is now completely disabled even though it is not grayed out, and therefore no message box is displayed.

Chris Bray

// Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
 
namespace MenuTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        private void testToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Test menuitem clicked");
        }
 
        private void removeHandlerButton_Click(object sender, EventArgs e)
        {
            testToolStripMenuItem.Click -= new System.EventHandler(this.testToolStripMenuItem_Click);
        }
    }
}
 
?? Form1.Designer.cs
 
namespace MenuTest
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;
 
        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }
 
        #region Windows Form Designer generated code
 
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.menuStrip1 = new System.Windows.Forms.MenuStrip();
            this.testToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.removeHandlerButton = new System.Windows.Forms.Button();
            this.menuStrip1.SuspendLayout();
            this.SuspendLayout();
            // 
            // menuStrip1
            // 
            this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.testToolStripMenuItem});
            this.menuStrip1.Location = new System.Drawing.Point(0, 0);
            this.menuStrip1.Name = "menuStrip1";
            this.menuStrip1.Size = new System.Drawing.Size(292, 24);
            this.menuStrip1.TabIndex = 0;
            this.menuStrip1.Text = "menuStrip1";
            // 
            // testToolStripMenuItem
            // 
            this.testToolStripMenuItem.Name = "testToolStripMenuItem";
            this.testToolStripMenuItem.Size = new System.Drawing.Size(40, 20);
            this.testToolStripMenuItem.Text = "&Test";
            this.testToolStripMenuItem.Click += new System.EventHandler(this.testToolStripMenuItem_Click);
            // 
            // removeHandlerButton
            // 
            this.removeHandlerButton.Location = new System.Drawing.Point(149, 216);
            this.removeHandlerButton.Name = "removeHandlerButton";
            this.removeHandlerButton.Size = new System.Drawing.Size(115, 23);
            this.removeHandlerButton.TabIndex = 1;
            this.removeHandlerButton.Text = "Remove Handler";
            this.removeHandlerButton.UseVisualStyleBackColor = true;
            this.removeHandlerButton.Click += new System.EventHandler(this.removeHandlerButton_Click);
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(292, 266);
            this.Controls.Add(this.removeHandlerButton);
            this.Controls.Add(this.menuStrip1);
            this.MainMenuStrip = this.menuStrip1;
            this.Name = "Form1";
            this.Text = "Form1";
            this.menuStrip1.ResumeLayout(false);
            this.menuStrip1.PerformLayout();
            this.ResumeLayout(false);
            this.PerformLayout();
 
        }
 
        #endregion
 
        private System.Windows.Forms.MenuStrip menuStrip1;
        private System.Windows.Forms.ToolStripMenuItem testToolStripMenuItem;
        private System.Windows.Forms.Button removeHandlerButton;
    }
}
 
// Program.cs
using System;
using System.Collections.Generic;
using System.Windows.Forms;
 
namespace MenuTest
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

Open in new window

0
 
asukhuAuthor Commented:
To chrisbray:

I tried your code. But it still doesn't do what I want: When I mouseover the menuitem, the item still highlights. What I want to do is remove that highlight? It there a way to some how override the highlight or totally disable it for this menuitem 'testToolStripMenuItem'?
0
 
chrisbrayCommented:
Hi asukhu:

I was answering the third part of your original question, namely:

> is there a way to have a menuitem disable without it being grayed out?

The code I provided does exactly that.

In order to produce the other effects that you seem to want, I can only suggest that you draw your own OwnerDraw menu.  This basically involves overriding the MeasureItem and DrawItem events on the menu.

Examples, Tutorials, Discussions on this topic:

http://www.csharphelp.com/archives/archive282.html
http://www.java2s.com/Code/CSharp/GUI-Windows-Form/OwnerDrawnMenu.htm
http://www.expresscomputeronline.com/20040119/techspace02.shtml

Chris Bray

0
 
chrisbrayCommented:
You may also wixh to review the MSDN entry on OwnerDraw menus:

http://msdn.microsoft.com/en-us/library/system.windows.forms.menuitem.ownerdraw.aspx

Chris Bray
0
 
asukhuAuthor Commented:
ok, Thanks for the info. I am going to do some more investigation and will post my results.
Thanks ChrisBray.
0
 
asukhuAuthor Commented:
I wrote my own customized menuRender to handling the highlight effects:

noHighlights : Arraylist contains all the names of the Tool Strip MenuItems that I wanted no highlighting for.

OnRenderMenuItemBackground : void Handles the logic for  handling this effect.
In addition to your code, i had to add to edit Form1.cs:

public Form1()
{
myCustomRender = new CustomRenderer();
InitializeComponent();
menuStrip1.Renderer = myCustomRender;
}


// CustomizedMenuItem.cs
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections;
 
namespace WindowsFormsUtils
{
    public class CustomizedMenuRenderer : ToolStripRenderer
    {
        ArrayList noHighlights = new ArrayList();
 
        public void addDisableHighlights(string menuItemName)
        {
            noHighlights.Add(menuItemName);
        }
        public void removeDisableHighlights(string menuItemName)
        {
            noHighlights.Remove(menuItemName);
        }
 
 
        protected override void OnRenderToolStripBackground(
         ToolStripRenderEventArgs e)
        {
            LinearGradientBrush brush = new LinearGradientBrush(e.AffectedBounds,
             Color.White, Color.Gray, 90f);
            e.Graphics.FillRectangle(brush, e.AffectedBounds);
            brush.Dispose();
        }
 
        protected override void OnRenderMenuItemBackground(ToolStripItemRenderEventArgs e)
        {
            bool showHighlight = true;
 
            showHighlight = !noHighlights.Contains(e.Item.Name);
            
 
            if (e.Item.Selected && showHighlight)
            {
                {
                    Rectangle rect = e.Item.ContentRectangle;
                    rect.X = e.Item.Padding.Left;
                    rect.Y = e.Item.Padding.Top;
                    rect.X -= 2;
                    rect.Y -= 5;
                    rect.Width -= 14;
                    rect.Height += 8;
 
                    LinearGradientBrush brush = new LinearGradientBrush(e.Item.Bounds,
             Color.Transparent, Color.LightBlue, 90);
                    e.Graphics.FillRectangle(brush, rect);
 
                    Pen outline = new Pen(Color.FromArgb(128, 128, 255), 1);
                    e.Graphics.DrawRectangle(outline, rect);
                }
            }
        }
    }
}

Open in new window

0
 
asukhuAuthor Commented:
Thanks for the tip (to write my own custom class), that really helped.
0
 
chrisbrayCommented:
Hi asukhu:

Glad to have been of help.  Your solution seems elegant enough and if it does what you want that can only be a good thing!

Chris Bray
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 6
  • 5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now