如何使Visual Studio Windows窗体设计器不会删除控件?

时间:2010-04-20 18:32:17

标签: .net vb.net winforms visual-studio-2008 windows-forms-designer

对于我的几种形式,我偶尔遇到以下问题:我使用设计器(Visual Studio 2008,Windows Forms,.NET 2.0,VB.NET)编辑表单以添加组件,但后来才发现进行了一些小的调整(例如,表格的大小突然改变几个像素),并且控件被删除。这是静默发生的 - 事件处理方法也自动删除了Handles后缀,因此它们永远不会被调用,并且没有编译器错误。我只是稍后注意到或者根本没注意到,因为我正在处理表单中的其他区域。

例如,我的表单中包含SplitContainer左侧的Infragistics UltraListView和右侧的UltraTabControl。我添加了一个新选项卡,并在其中进行控制,并且它们工作正常。我后来发现列表视图的滚动条突然不可见,因为它的大小已经关闭,并且至少有一个控件已从我没有使用的其他选项卡中删除。

这是WinForms Designer或Infragistics的已知问题吗?当然,我使用版本控制,因此我可以比较更改并将已删除的代码合并回来,但这是一个繁琐的过程,不应该是必要的。有办法避免这种情况吗?有没有充分的理由发生这种情况?

一个线索是,被删除的控件可能包含期望在运行时运行的代码(例如Load事件处理程序),而不是设计时间,并且可能抛出异常。这会导致Visual Studio删除控件吗?

6 个答案:

答案 0 :(得分:10)

这不是您问题的答案,但请记住,您应该在加载中使用“DesignMode”。这可以避免在设计时出现奇怪的意外行为。

private void EureFormAbm_Load(object sender, System.EventArgs e)
{
    if (!DesignMode)
    {
        // Your code
    } /* if */
}

private void EureFormAbm_Load(object sender, System.EventArgs e)
{
    if (DesignMode)
        return;
    // Your code
}

答案 1 :(得分:2)

如果您可以重现问题,那么您可以确定原因是否是例外。启动Visual Studio的第二个实例,并使用“Tools-> Attach to Process”附加到第一个实例。然后继续重现问题,并且在抛出未处理的异常时代码应该中断。有关其他异常(可能已处理)的信息将在“输出”窗口中显示。

答案 2 :(得分:1)

这不是一个真正的答案,但这里有一些我发现有帮助的指针......

<强> A) 请参阅@Daniel Dolz的回答。我全心全意地建议你总是做他推荐的事情,除非你完全避免在Form_Load中放入非UI代码(或任何代码)。这实际上解决了很多问题,但尤其是那些在设计师中出现的异常和设计师的性能降低。

B)尽可能多的人:

永远不要在Windows Forms 中编辑designer.cs。

好的,有时候你必须这样做,但是这不是定期开发的地方。第三方控件会出现需要您执行此操作的错误,但是当您在设计器文件中进行直接更改时,这应该是非常罕见的一天。一种帮助管理的方法是,如果您不希望设计师自动调整某些内容,请将其复制到常规.cs文件中。这并不涵盖所有内容,但要记住它。

C)另外,您是否知道可以通过IDE 锁定布局,以防止鼠标点击鼠标乱搞你的一切?这将抢占您遇到的一些“自动更新”。

分手镜头我在当前项目之前的一个大型Windows窗体项目工作了两年多,我只能说是在我们结束人们编辑设计师之前,除了非常小的编辑并要求他们放入DesignMode检查,我们只有问题。关于Web项目,我们很难有这个想法,因为我们习惯于编辑标记,但designer.cs与标记不同。

答案 3 :(得分:1)

我发现DesignMode属性有时会产生意外结果(Daniel的回答)。下面是我在我的基本控件类上的属性(我创建的大多数控件继承自此),注释应该指示看起来像hacky代码的“原因”,但实际上这比自己的DesignMode更可靠。 / p>

    /// <summary>
    /// Indicates if the current view is being utilized in the VS.NET IDE or not.
    /// </summary>
    /// <remarks>The DesignMode property for a UserControl object will show that it is in DesignMode
    /// only if the immediate parent is viewed in the IDE; if it is a grand child of the object that is being viewed in the IDE,
    /// then the DesignMode property will not be true.
    /// This is a workaround</remarks>
    public bool InDesignMode
    {
        get
        {
            // Site.Design mode sometimes produces a better result.
            if (DesignMode || Site != null && Site.DesignMode)
                return true;
            Control parent = Parent;
            while (parent != null)
            {
                if (parent.Site != null && parent.Site.DesignMode)
                    return true;
                parent = parent.Parent;
            }

            // Note: I am not 100% sure about this one; I need to double check
            // if in design mode then entryAssembly will be null. This check is 
            // needed because DesignMode property is only true for the control
            // that is actively being designed, so child controls will be false...
            // We do check the Parent heirarchy in InDesignMode but in some 
            // cases Parent will not be set before the check is required.
            var entryAssembly = Assembly.GetEntryAssembly();
            if (entryAssembly == null)
                return true;

            return false;
        }
    }

答案 4 :(得分:0)

我已经看到,当操作系统遇到问题时,Visual Basic 6.0和早期的.NET会发生这种情况。我们不得不重新启动并修复。

答案 5 :(得分:0)

另一个好习惯,不要删除默认的表单构造函数。 IDE使用它们,即使您的逻辑没有。 锁定也很有用。