Question

I want to disable the dropdown shadow on the dropdown of a ToolStripDropDownButton. If the dropdown menu contains items that have dropdowns themselves (e.g. multi-level menu) then setting the DropShadowEnabled to false on the ToolStripDropDownButton causes the top level dropdown to appear at the wrong position. See attached picture.

enter image description here

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        toolStripDropDownButton1.DropDown.DropShadowEnabled = false;
    }
}


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()
    {
        System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
        this.toolStrip1 = new System.Windows.Forms.ToolStrip();
        this.toolStripDropDownButton1 = new System.Windows.Forms.ToolStripDropDownButton();
        this.item1ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
        this.subitem1ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
        this.toolStrip1.SuspendLayout();
        this.SuspendLayout();
        // 
        // toolStrip1
        // 
        this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
        this.toolStripDropDownButton1});
        this.toolStrip1.Location = new System.Drawing.Point(0, 0);
        this.toolStrip1.Name = "toolStrip1";
        this.toolStrip1.Size = new System.Drawing.Size(292, 25);
        this.toolStrip1.TabIndex = 0;
        this.toolStrip1.Text = "toolStrip1";
        // 
        // toolStripDropDownButton1
        // 
        this.toolStripDropDownButton1.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
        this.toolStripDropDownButton1.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
        this.item1ToolStripMenuItem});
        this.toolStripDropDownButton1.Image = ((System.Drawing.Image)(resources.GetObject("toolStripDropDownButton1.Image")));
        this.toolStripDropDownButton1.ImageTransparentColor = System.Drawing.Color.Magenta;
        this.toolStripDropDownButton1.Name = "toolStripDropDownButton1";
        this.toolStripDropDownButton1.Size = new System.Drawing.Size(29, 22);
        this.toolStripDropDownButton1.Text = "toolStripDropDownButton1";
        // 
        // item1ToolStripMenuItem
        // 
        this.item1ToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
        this.subitem1ToolStripMenuItem});
        this.item1ToolStripMenuItem.Name = "item1ToolStripMenuItem";
        this.item1ToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
        this.item1ToolStripMenuItem.Text = "item1";
        // 
        // subitem1ToolStripMenuItem
        // 
        this.subitem1ToolStripMenuItem.Name = "subitem1ToolStripMenuItem";
        this.subitem1ToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
        this.subitem1ToolStripMenuItem.Text = "subitem1";
        // 
        // Form1
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(292, 273);
        this.Controls.Add(this.toolStrip1);
        this.Name = "Form1";
        this.Text = "Form1";
        this.toolStrip1.ResumeLayout(false);
        this.toolStrip1.PerformLayout();
        this.ResumeLayout(false);
        this.PerformLayout();

    }

    #endregion

    private System.Windows.Forms.ToolStrip toolStrip1;
    private System.Windows.Forms.ToolStripDropDownButton toolStripDropDownButton1;
    private System.Windows.Forms.ToolStripMenuItem item1ToolStripMenuItem;
    private System.Windows.Forms.ToolStripMenuItem subitem1ToolStripMenuItem;
}
Was it helpful?

Solution

This is very typical lossage in the ToolStripItem classes. Clearly it is a bug, it probably got introduced when they applied a hack to work around a Windows problem. You can still see the internal bug number in the Reference Source:

public bool DropShadowEnabled {
    get {
        // VSWhidbey 338272 - DropShadows are only supported on TopMost windows
        // due to the flakeyness of the way it's implemented in the OS. (Non toplevel
        // windows can have parts of the shadow disappear because another window can get
        // sandwiched between the SysShadow window and the dropdown.)
        return dropShadowEnabled && TopMost && DisplayInformation.IsDropShadowEnabled;
    }
    set {  // etc... }
}

But without a corresponding fix in the setter and the renderer.

The flakeyness they mentioned actually got fixed in Vista, you are still running on XP so you can't see it. Drop shadows are done differently on the Aero desktop and it is a system setting whether or not they are enabled. So using the property is entirely ineffective on Aero.

These ToolStripItem class bugs didn't get fixed after the .NET 2.0 release, about the entire Winforms team moved over to the WPF group. And they are certainly not getting fixed now, no point filing a bug at connect.microsoft.com although you are free to do so.

With the added wrinkle that the property just cannot have an effect anymore on later versions of Windows since it is now a system setting, the only logical thing to do here is to throw in the towel. Don't change the property.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top