【问题标题】:Check only one ToolStripMenuItem只检查一个 ToolStripMenuItem
【发布时间】:2012-11-16 05:17:23
【问题描述】:

我有一个ToolStrip 和多个ToolStripDropDownButtons,每个都有一组DropDownItems

当用户点击 DropDownItem 时,会显示复选标记。

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

我想要做的是当用户点击一个 DropDownItem 时,其他已经选中的项目应该被取消选中。换句话说,DropDown 列表中应该始终只有一个选中项。

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

以下是我目前拥有的代码。

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;
                }
            }
        }

如果有人能对此有所了解或告诉我一个简单的方法,我将不胜感激。

谢谢。

【问题讨论】:

标签: winforms checked toolstrip toolstripdropdown toolstripitem


【解决方案1】:

这么简单……

按如下所述实现他们的方法:

    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();
    }

一个细节是您可以为所有单击 menuItens 实现相同的方法,为此将相同的方法调用 UncheckOtherToolStripMenuItems((ToolStripMenuItem)sender); 添加到每个 ToolstripMenuItem 的事件单击中,请参阅此示例到另外两个 ToolstripMenuItens:

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

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

【讨论】:

  • 感谢您的回复,但它仅适用于 DropDownList 中的第一个 ToolStripMenuItem。
  • 我正在编辑答案。如果满足您的需求,请评价问题
  • 谢谢。有用。但是我遇到了一个小问题。当下拉列表中有ToolStripSeparators 时,我得到一个 InvalidCastException。 无法将“System.Windows.Forms.ToolStripSeparator”类型的对象转换为“System.Windows.Forms.ToolStripMenuItem”类型。您有什么建议可以反驳吗?再次感谢。 :)
  • @Isuru,很抱歉没有考虑到这个细节,我编辑了帖子,将 lambda 表达式交换为一个 linq 查询,该查询检查检查或不检查 ToolStripMenuItem 所需的所有条件。
  • @isuru,Linq 很酷!!!看这个学习:code.msdn.microsoft.com/101-LINQ-Samples-3fb9811blinqpad.net
【解决方案2】:

我只是使用 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);
        }

【讨论】:

    【解决方案3】:

    我有另一种方法:

    每个项目都将发送到ToolStripMenuItem_CheckStateChanged(object sender, EventArgs e) 每个项目都有自己的标签1, 2, 3, 4, 5。 一个项目在开始时被检查并且有tag = 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;
        }
    

    【讨论】:

      【解决方案4】:

      最简单的方法是添加 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;
              }
          }
      

      【讨论】:

        【解决方案5】:

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

        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);
        

        【讨论】:

          猜你喜欢
          • 2022-06-15
          • 2012-12-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-12-01
          • 2015-07-20
          相关资源
          最近更新 更多