Winforms 仅检查一个ToolStripMenuItem

Winforms 仅检查一个ToolStripMenuItem,winforms,checked,toolstrip,toolstripdropdown,toolstripitem,Winforms,Checked,Toolstrip,Toolstripdropdown,Toolstripitem,我有一个ToolStrip和多个ToolStripDropDownButtons,每个按钮都有一组DropDownItems 当用户单击下拉项时,将显示复选标记 默认情况下,可以单击多个项目,因此会显示多个复选标记 我试图做的是,当用户单击一个下拉项时,其他已经选中的项应该被取消选中。换句话说,下拉列表中应该始终只有一个选中项 我已经涉猎了一段时间,但我真的不知道如何在取消选中其他项目的同时保持当前选中项目的状态 以下是我目前拥有的代码 private void subietm1ToolSt

我有一个
ToolStrip
和多个
ToolStripDropDownButton
s,每个按钮都有一组
DropDownItems

当用户单击下拉项时,将显示复选标记

默认情况下,可以单击多个项目,因此会显示多个复选标记

我试图做的是,当用户单击一个下拉项时,其他已经选中的项应该被取消选中。换句话说,下拉列表中应该始终只有一个选中项

我已经涉猎了一段时间,但我真的不知道如何在取消选中其他项目的同时保持当前选中项目的状态

以下是我目前拥有的代码

private void subietm1ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            UncheckOtherToolStripMenuItems(sender);
        }

        public void UncheckOtherToolStripMenuItems(object selectedMenuItem)
        {
            List<ToolStripDropDownButton> dropdownButtons = new List<ToolStripDropDownButton>();
            foreach (ToolStripItem item in toolStrip1.Items)
            {
                if (item is ToolStripDropDownButton)
                {
                    dropdownButtons.Add((ToolStripDropDownButton)item);
                }
            }

            foreach (ToolStripDropDownButton btn in dropdownButtons)
            {
                foreach (ToolStripMenuItem d in btn.DropDownItems)
                {
                    if (d.Checked)
                        d.CheckState = CheckState.Unchecked;
                }
            }
        }
private void子文件M1ToolStripMenuItem\u单击(对象发送方,事件参数e)
{
取消选中其他ToolStripMenuItems(发送方);
}
public void取消选中其他工具条带菜单项(对象选择菜单项)
{
列表下拉按钮=新建列表();
foreach(toolStrip1.Items中的ToolStripItem项)
{
if(项目为ToolStripDropDownButton)
{
添加((ToolStripDropDownButton)项);
}
}
foreach(下拉按钮中的ToolStripDropDownButton btn)
{
foreach(btn.DropDownItems中的ToolStripMenuItem d)
{
如果(d.选中)
d、 CheckState=CheckState.Unchecked;
}
}
}
如果有人能解释一下,或者告诉我一个简单的方法,我将不胜感激

谢谢。

太简单了

按如下所述实施其方法:

    private void subietm1ToolStripMenuItem_Click(object sender, EventArgs e)
    {
        UncheckOtherToolStripMenuItems((ToolStripMenuItem)sender);
    }

    public void UncheckOtherToolStripMenuItems(ToolStripMenuItem selectedMenuItem)
    {
        selectedMenuItem.Checked = true;

        // Select the other MenuItens from the ParentMenu(OwnerItens) and unchecked this,
        // The current Linq Expression verify if the item is a real ToolStripMenuItem
        // and if the item is a another ToolStripMenuItem to uncheck this.
        foreach (var ltoolStripMenuItem in (from object 
                                                item in selectedMenuItem.Owner.Items 
                                            let ltoolStripMenuItem = item as ToolStripMenuItem 
                                            where ltoolStripMenuItem != null 
                                            where !item.Equals(selectedMenuItem) 
                                            select ltoolStripMenuItem))
            (ltoolStripMenuItem).Checked = false;

        // This line is optional, for show the mainMenu after click
        selectedMenuItem.Owner.Show();
    }
一个细节是,您可以为所有click MenuItems实现相同的方法,为此,请为方法添加相同的调用
UncheckOtherToolStripMenuItems((ToolStripMenuItem)sender)编码到事件中,为每个ToolstripMenuItem单击,请参见此示例以了解另外两个ToolStripMenuItems:

    private void subietm2ToolStripMenuItem_Click(object sender, EventArgs e)
    {
        UncheckOtherToolStripMenuItems((ToolStripMenuItem)sender);
    }

    private void subietm3ToolStripMenuItem_Click(object sender, EventArgs e)
    {
        UncheckOtherToolStripMenuItems((ToolStripMenuItem)sender);
    }

我只是用item_Click事件设置我菜单中的所有项目,因此如果单击其中一个,它将只运行下面的代码。这样,每个按钮都不需要事件

    private void item_Click(object sender, EventArgs e)
    {
        // Set the current clicked item to item
        ToolStripMenuItem item = sender as ToolStripMenuItem;
        // Loop through all items in the subMenu and uncheck them but do check the clicked item
        foreach (ToolStripMenuItem tempItemp in (ToolStripMenuItem)item.OwnerItem.DropDownItems)
        {
            if (tempItemp == item)
                tempItemp.Checked = true;
            else
                tempItemp.Checked = false;
        }
    }
如果您想在运行时将多个项目添加到列表中,并以上面的方式将它们连接起来,则可以运行下面的代码

    private void subItemsMenus(ToolStripMenuItem parentItem, string[] listItems)
    {
        // Clear tool strip items first
        parentItem.DropDownItems.Clear();
        // Add items that are in the list
        foreach (string subMenuItem in listItems)
        {
            ToolStripMenuItem item = new ToolStripMenuItem();
            //Name that will appear on the menu
            item.Text = subMenuItem; 
            //Put in the Name property whatever necessary to retrieve your data on click event
            item.Name = subMenuItem;
            //On-Click event
            item.Click += new EventHandler(item_Click);
            //Add the submenu to the parent menu
            parentItem.DropDownItems.Add(item);
        }

您可以通过复制到数组,然后使用扩展名来获取计数

ToolStripItem[] controls = new ToolStripItem[ToolStrip.DropDownItems.Count];
ToolStrip.DropDownItems.CopyTo(controls,0);
intcheckCount = controls.Count(c => (c as ToolStripMenuItem).Checked);

if (checkCount == 0) // must keep 1 selection
     item.Checked = true;
else if (checkCount > 1)  //uncheck all others
     controls.Cast<ToolStripMenuItem>().Where(c => c.Checked && c.Name != item.Name)
       .ToList().ForEach(s => s.Checked = false);
ToolStripItem[]controls=newtoolstripItem[ToolStrip.DropDownItems.Count];
ToolStrip.DropDownItems.CopyTo(控件,0);
intcheckCount=controls.Count(c=>(c作为ToolStripMenuItem.Checked);
if(checkCount==0)//必须保留1个选择
item.Checked=true;
else if(checkCount>1)//取消选中所有其他项
controls.Cast()。其中(c=>c.Checked&&c.Name!=item.Name)
.ToList().ForEach(s=>s.Checked=false);

我有另一种方法:

每个项目都将进入
ToolStripMenuItem\u CheckStateChanged(对象发送方,事件参数e)
每个项目都有自己的标签
1,2,3,4,5
。 一个项目在开始时被选中,并且具有
标记=1

    int selecteditem = 1;
    bool atwork = false;
    private void dzienToolStripMenuItem_CheckStateChanged(object sender, EventArgs e)
    {
        if (atwork) return;
        else atwork = true;

        selecteditem = Convert.ToInt32(((ToolStripMenuItem)sender).Tag);

        foreach (ToolStripMenuItem it in sometooltipdropdown.DropDownItems)
        {
            if (Convert.ToInt32(it.Tag) != selecteditem)
            {
                it.Checked = false;
            }                
        }

        atwork = false;
    }

最简单的方法是添加DropDownItemClicked事件并创建自己的方法:

private void toolStripDropDownButton1_DropDownItemClicked(object sender, ToolStripItemClickedEventArgs e)
    {
        if (e.ClickedItem != null)
        {
            CheckSelected((ToolStripDropDownButton)sender, e.ClickedItem);
        }
    }

    private void CheckSelected(ToolStripDropDownButton button, ToolStripItem selectedItem)
    {
        foreach (ToolStripMenuItem item in button.DropDownItems)
        {
            item.Checked = (item.Name == selectedItem.Name) ? true : false;
        }
    }

感谢您的回复,但它只适用于DropDownList中的第一个ToolStripMenuItem。我编辑了答案。如果满足您的需要,请对问题进行评分。谢谢。它起作用了。然而,我面临一个小问题。当dropdownlist中有
ToolStripSeparator
s时,我得到一个InvalidCastException。无法将“System.Windows.Forms.ToolStripSeparator”类型的对象强制转换为“System.Windows.Forms.ToolStripMenuItem”类型。你有什么反对的建议吗?再次感谢。:)@Isuru,很抱歉没有想到这个细节,我编辑了将lambda表达式替换为linq查询的帖子,该查询检查是否检查ToolStripMenuItem所需的所有条件。@Isuru,linq很酷!!!有关研究,请参见: