【问题标题】:ToolStripMenuItem strange behavior on visible property [duplicate]ToolStripMenuItem 可见属性上的奇怪行为[重复]
【发布时间】:2021-08-17 20:11:08
【问题描述】:

我很久以前和现在都遇到过这个问题。我无法弄清楚在表单加载时编辑ToolStripMenuItem 控件Visible 属性需要做些什么特别的事情。

在 Designer.cs 中

private System.Windows.Forms.ToolStripMenuItem mnuExport;
// 
// mnuExport
// 
this.mnuExport.Name = "mnuExport";
this.mnuExport.Size = new System.Drawing.Size(116, 22);
this.mnuExport.Text = "Export";
this.mnuExport.Visible = false;
this.mnuExport.Click += new System.EventHandler(this.mnuExport_Click);

在表单代码中

public partial class MainBuilder : Form
{
    private void MainBuilder_Load(object sender, EventArgs e)
    {
        mnuExport.Visible = true;
    }
}

在上面的代码中,export 是一个ToolStripMenuItem 类型的菜单项,它通过表单设计模式中的属性网格我已将其Visible 属性修改为false。所以在表单加载中我想切换到可见状态为真。我认为这很容易,所以我编写了所有的逻辑,但它失败了。所以我决定删除我的所有代码并简单地将集合硬编码为 true,令我惊讶的是这不起作用。

当我将断点放在 form_load 的行上时,我清楚地看到它是假的,如果它让行运行,值仍然是假的。

我记得过去看到过这个问题,但找不到任何相关信息。我还尝试在该窗口中使用 4-5 个其他菜单项,它们都显示相同的行为。

编辑 只是尝试将visible = true 放在designer.cs 中,而在form_load 中仍然告诉我该值为false。这里有一些主要问题。

【问题讨论】:

  • 将代码移至 Shown 事件。还要检查所有者是否可见。
  • 可能有两个原因。一种是如果你把断点放在 mnuExport.Visible = true; 行上。你必须用F10追踪,看看它是否仍然是假的?另一个提示是,您必须在上次它变为假之后找到另一个事件来设置它。我建议创建一个带有 onvisibleChange 的方法并制作一个消息框或打印行来查看它在哪个部分更改为 false 和 true,然后您可以在代码中找到该特定位置。
  • @Hamed_gibago ToolStripMenuItem 通常在 需要它们存在 之前是不可见的 :) 我建议在 Shown 事件中设置 Visible 属性,这样设置时会发生什么可能会变得很清楚排序菜单中的该属性。检查所有者的价值。如果将 Owner 的 Visible 属性设置为 true 并且 Owner 是顶级 MenuItem...
  • 在您的MainBuilder_Load 事件处理程序中,您的表单不可见。因此,您表单上的所有内容也不可见。如果您将任何 Visible 属性设置为 true 并没有什么区别,它只会在您的表单变得可见后才会生效。
  • @Steeeve 听起来你在问警察 :) 这不是我能说的。我只是尝试分享我所知道的。总结一下:MenuItems (ToolStripItems) 的Visible 属性是一个兼容特性。这是一种缓存状态。属性返回:(ParentInternal!=null) && (ParentInternal.Visible) && Available。因此,Available 属性更相关。所有子菜单项始终具有其Visible 属性= false,除非菜单显示在屏幕上。只有顶级 MenuItem(例如,所有者是 MenuStrip)返回 Visible = true

标签: c# winforms .net-4.8


【解决方案1】:

如 cmets 中所述,属性 Visible getter 直到生命周期的后期才反映实际的内部属性值。它在form_loaded 事件中仍然不可用。我的主要问题是一个菜单可见性状态是基于如果所有子菜单都不可见,那么它也不应该。为此,我正在迭代它的孩子并检查 Visible 属性。问题是他们拥有Visiblefalse,因为它的工作方式父级也将它自己的Visible 设置为false

我不喜欢这个解决方案,但这是让它发挥作用的唯一方法

// get all sub menus
var subMenus = mnuExport.DropDownItems.Cast<ToolStripItem>().ToList();

// create a list of bool that will store the visible state I want the controls to have. put them to true by default
var menusVisibleStates = Enumerable.Repeat(true, menus.Count).ToList();

// set the visibility state of each sub menus
for (int i = 0; i < menus.Count; i++)
{
    // some logic is here that choose true or false but is irrelevant here
    var visibleStateIWant = true; 

    // set the visible state stored
    menusVisibleStates[i] = false;

    // set the actual control value that will change later on
    menus[i].Visible = false;
}

/// now here I use the state I have specified and NOT the menu object property
mnuExport.Visible = menusVisibleStates.Any(o => o);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-24
    • 2011-12-07
    • 2021-09-11
    • 1970-01-01
    • 2016-10-05
    • 1970-01-01
    • 2017-04-10
    • 1970-01-01
    相关资源
    最近更新 更多