继承的 Windows 窗体上的面板行为不正确?

发布于 2024-10-16 21:57:32 字数 4058 浏览 4 评论 0原文

我需要一个解决方法来解决继承的 Windows 窗体上面板的错误行为。我有几个按钮应该固定在面板的右下角,但它们的位置以我无法预测继承形式的方式变化。我尝试过 Dock 和 Anchor 属性的各种组合,但到目前为止还没有任何方法可以使按钮显示在应有的位置。所有控件都标记为“受保护”。

基本表单本身的行为是正确的。不正确的行为仅发生在继承表单上;按钮锚定到其父面板。

如果我将按钮锚定在左上角,我可以将继承的表单的大小调整得更大,最终按钮将在基本表单大小之外的某个位置被发现。如果我将按钮固定在右下角,我就无法使表单足够大以露出按钮。

我尝试创建一个继承Panel 的自定义面板和一个GroupBox,但它们的工作方式没有任何不同。我也有同样的运气,将按钮直接放在表单上,​​没有容器。

我想要的:可调整大小的表单底部有一个面板,右下角有我的按钮。表单的其余部分应该是 DataGridView 的可调整大小的区域(我已经解决了这个问题的继承和对接问题>:-/)无论窗口大小如何,按钮都应该始终位于右下角。我不想调整按钮的大小。

如果我必须自己调整控件的大小,我愿意这样做。但如果框架能够正确地做到这一点,而我只需要学习如何正确使用它,我会更喜欢教育。

我发现这个链接似乎描述了类似的不当行为:如何阻止按钮以继承形式移动。尚未得到答复。


这是从我遇到问题的程序中提取的一些代码。

基本表单

// 
// refreshButton
// 
this.refreshButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.refreshButton.Location = new System.Drawing.Point(200, 4);
this.refreshButton.Name = "refreshButton";
this.refreshButton.Size = new System.Drawing.Size(75, 23);
this.refreshButton.TabIndex = 5;
this.refreshButton.Text = "&Refresh";
this.refreshButton.UseVisualStyleBackColor = true;
// 
// saveButton
// 
this.saveButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.saveButton.Location = new System.Drawing.Point(281, 5);
this.saveButton.Name = "saveButton";
this.saveButton.Size = new System.Drawing.Size(75, 23);
this.saveButton.TabIndex = 4;
this.saveButton.Text = "&Save";
this.saveButton.UseVisualStyleBackColor = true;
// 
// buttonPanel
// 
this.buttonPanel.Controls.Add(this.saveButton);
this.buttonPanel.Controls.Add(this.refreshButton);
this.buttonPanel.Dock = System.Windows.Forms.DockStyle.Bottom;
this.buttonPanel.Location = new System.Drawing.Point(0, 231);
this.buttonPanel.Name = "buttonPanel";
this.buttonPanel.Size = new System.Drawing.Size(360, 31);
this.buttonPanel.TabIndex = 6;

继承表单(调整大小以适合我的数据内容)

// 
// refreshButton
// 
this.refreshButton.Location = new System.Drawing.Point(286, 7);
this.refreshButton.TabIndex = 0;
// 
// saveButton
// 
this.saveButton.Location = new System.Drawing.Point(367, 7);
this.saveButton.TabIndex = 1;
// 
// buttonPanel
// 
this.buttonPanel.Location = new System.Drawing.Point(0, 232);
this.buttonPanel.Size = new System.Drawing.Size(445, 33);

编辑:更多使用后的一些附加数据。该问题似乎是 Visual Studio 2005 设计器中的错误,或者设计器和 C# 编译器之间的奇怪交互。当我创建继承的表单时,按钮被重新定位到表单边缘之外的某个任意(但不是随机!)位置。这些按钮仍然可用,并且可以使用 VS 属性窗口的控件下拉菜单进行选择。

我可以选择控件并修复它们的位置,使它们在设计图面和运行时显示在正确的位置。当我调整表单大小时,它们甚至可以正确移动。然而,在构建之后,设计者会修改按钮的可见位置。 *.Designer.cs 文件中的代码仍然正确,但按钮属性已更改。在上面继承的表单中,设计器的刷新按钮和保存按钮的位置属性为 371,7 和 452,7,即使包含面板只有 445 像素宽。

至少这个新信息给了我部分修复,但我仍然不知道为什么会发生这种情况。


答案:嗯,事实证明按钮实际上确实固定在面板上。不幸的是,设计者将锚点位置更改为窗体可见区域之外的某个位置。结论是VS2005设计器不可靠并且不能100%正确地处理继承的表单。

我推断出的解决方法是重写基本表单中的 OnResize() 方法并更正按钮的位置。这是一个小技巧,但满足了我的需求。

/// <summary>
/// Must handle some layout operations manually because Visual Studio 
/// 2005 arbitrarily changes some properties of inherited controls.
/// </summary>
/// <param name="e">Data for event.</param>
protected override void OnResize(EventArgs e)
{
    base.OnResize(e);

    // Move Refresh and Save buttons to lower right corner of button panel.
    saveButton.Top = buttonPanel.Bounds.Height -
        (saveButton.Height + saveButton.Padding.Bottom + saveButton.Margin.Bottom);
    saveButton.Left = buttonPanel.Bounds.Width -
        (saveButton.Width + saveButton.Padding.Right + saveButton.Margin.Right);
    refreshButton.Top = saveButton.Top;
    refreshButton.Left = saveButton.Left -
        (refreshButton.Width + refreshButton.Padding.Right + refreshButton.Margin.Right);
}

I need a workaround for incorrect behavior for a Panel on an inherited stock Windows Form. I have a couple buttons that are supposed to be anchored to the bottom right corner of the panel, but their locations vary in a manner I cannot predict on inherited forms. I've tried various combinations of Dock and Anchor properties, but nothing so far makes the buttons show up where they are supposed to. All controls are marked Protected.

Behavior is correct on the base form itself. The incorrect behavior happens only on inherited forms; the buttons are not anchored to their parent panel.

If I anchor the buttons to the top left, I can resize the inherited form bigger and eventually the buttons will be uncovered, somewhere outside the base form size. If I anchor the buttons to the bottom right, I have been unable to make the form big enough to ever uncover the buttons.

I've tried creating a custom panel that inherits Panel, and a GroupBox, but these didn't work any differently. I had the same luck putting the buttons directly on the form, without a container.

What I want: a Panel at the bottom of a resizable Form with my buttons in the lower right corner of it. The remainder of the form should be a resizable area for a DataGridView (I've already worked through the inheritance and docking problems with this one >:-/) The buttons should always be in the bottom right corner regardless of the window size. I don't want to resize the buttons.

If I have to resize the controls myself, I'm willing to do that. But if the framework will do it correctly, and I just need to learn how to use it properly, I would prefer the education.

I found this link that appears to be describing similar misbehavior: How to stop buttons from moving in inherited form. It hasn't been answered.


Here is some code extracted from the program I'm having a problem with.

Base form

// 
// refreshButton
// 
this.refreshButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.refreshButton.Location = new System.Drawing.Point(200, 4);
this.refreshButton.Name = "refreshButton";
this.refreshButton.Size = new System.Drawing.Size(75, 23);
this.refreshButton.TabIndex = 5;
this.refreshButton.Text = "&Refresh";
this.refreshButton.UseVisualStyleBackColor = true;
// 
// saveButton
// 
this.saveButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.saveButton.Location = new System.Drawing.Point(281, 5);
this.saveButton.Name = "saveButton";
this.saveButton.Size = new System.Drawing.Size(75, 23);
this.saveButton.TabIndex = 4;
this.saveButton.Text = "&Save";
this.saveButton.UseVisualStyleBackColor = true;
// 
// buttonPanel
// 
this.buttonPanel.Controls.Add(this.saveButton);
this.buttonPanel.Controls.Add(this.refreshButton);
this.buttonPanel.Dock = System.Windows.Forms.DockStyle.Bottom;
this.buttonPanel.Location = new System.Drawing.Point(0, 231);
this.buttonPanel.Name = "buttonPanel";
this.buttonPanel.Size = new System.Drawing.Size(360, 31);
this.buttonPanel.TabIndex = 6;

Inherited form (resized to fit my data contents)

// 
// refreshButton
// 
this.refreshButton.Location = new System.Drawing.Point(286, 7);
this.refreshButton.TabIndex = 0;
// 
// saveButton
// 
this.saveButton.Location = new System.Drawing.Point(367, 7);
this.saveButton.TabIndex = 1;
// 
// buttonPanel
// 
this.buttonPanel.Location = new System.Drawing.Point(0, 232);
this.buttonPanel.Size = new System.Drawing.Size(445, 33);

Edit: some additional data after playing around with it more. The problem seems to a bug in the Visual Studio 2005 designer, or strange interaction between the designer and C# compiler. When I create my inherited form, the buttons are relocated to some arbitrary (but not random!) location off the edge of the form. The buttons are still available and selectable using the control dropdown of the VS Properties window.

I can select the controls and repair their locations to have them show up in the correct place on the design surface and at runtime. They even move correctly when I resize the form. However, after a build, the designer modifies the visible Location of the buttons. The code in the *.Designer.cs file is still correct, but the button properties are changed. In the inherited form from above, the designer's Location properties for the refreshButton and saveButton are 371,7 and 452,7 even though the containing panel is only 445 pixels wide.

At least this new information gives me a partial fix, but I still don't know why it happens.


Answer: Well, it turns out the buttons actually do stay anchored to the panel. Unfortunately, the designer changes the anchor location to be somewhere off the visible area of the form. The conclusion is that the VS2005 designer is unreliable and doesn't handle inherited forms 100% correctly.

The workaround I deduced was to override the OnResize() method in my base form and correct the buttons' locations there. It's a small hack, but meets my needs.

/// <summary>
/// Must handle some layout operations manually because Visual Studio 
/// 2005 arbitrarily changes some properties of inherited controls.
/// </summary>
/// <param name="e">Data for event.</param>
protected override void OnResize(EventArgs e)
{
    base.OnResize(e);

    // Move Refresh and Save buttons to lower right corner of button panel.
    saveButton.Top = buttonPanel.Bounds.Height -
        (saveButton.Height + saveButton.Padding.Bottom + saveButton.Margin.Bottom);
    saveButton.Left = buttonPanel.Bounds.Width -
        (saveButton.Width + saveButton.Padding.Right + saveButton.Margin.Right);
    refreshButton.Top = saveButton.Top;
    refreshButton.Left = saveButton.Left -
        (refreshButton.Width + refreshButton.Padding.Right + refreshButton.Margin.Right);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

孤凫 2024-10-23 21:57:32

让我们看一些重复该行为的代码。这段代码没有:

using System;
using System.Drawing;
using System.Windows.Forms;

class FormBase : Form
{
    public FormBase()
    {
        Panel panel;
        Controls.Add(panel = new Panel { Dock = DockStyle.Bottom, Height = 120, BackColor = Color.LightGray });
        panel.Controls.Add(new Button { Text = "Button 1", Anchor = AnchorStyles.Bottom | AnchorStyles.Right, Location = new Point(panel.ClientSize.Width - 80, panel.ClientSize.Height - 60) });
        panel.Controls.Add(new Button { Text = "Button 2", Anchor = AnchorStyles.Bottom | AnchorStyles.Right, Location = new Point(panel.ClientSize.Width - 80, panel.ClientSize.Height - 30) });
    }
}

class FormInherited : FormBase
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new FormInherited());
    }
}

Let's see some code that duplicates the behavior. This code doesn't:

using System;
using System.Drawing;
using System.Windows.Forms;

class FormBase : Form
{
    public FormBase()
    {
        Panel panel;
        Controls.Add(panel = new Panel { Dock = DockStyle.Bottom, Height = 120, BackColor = Color.LightGray });
        panel.Controls.Add(new Button { Text = "Button 1", Anchor = AnchorStyles.Bottom | AnchorStyles.Right, Location = new Point(panel.ClientSize.Width - 80, panel.ClientSize.Height - 60) });
        panel.Controls.Add(new Button { Text = "Button 2", Anchor = AnchorStyles.Bottom | AnchorStyles.Right, Location = new Point(panel.ClientSize.Width - 80, panel.ClientSize.Height - 30) });
    }
}

class FormInherited : FormBase
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new FormInherited());
    }
}
迷离° 2024-10-23 21:57:32

我通过锚定继承的形式得到了非常不可靠的结果。

我发现,如果您尽可能地停靠控件(而不是锚定),似乎一切都会更好,即使这意味着将控件放置在面板内的面板上。 (你确实说过解决问题吧?!)

I have had very unreliable results with anchoring on inherited forms.

I've found it seems to all work better if you dock controls where ever possible (instead of anchoring), even if this means placing controls on panels within panels. (You did say work around right?!)

娇妻 2024-10-23 21:57:32

我对面板也有同样的问题。
要解决此问题,请首先在父窗体的设计器中设置锚点属性。
然后,转到构建->重建解决方案。

这也应该适用于旧版本的 Visual Studio。

编辑:
对于按钮,您需要处理调整大小事件,正如其他答案所建议的那样。

I had the same problem with Panels.
To fix this, first set the Anchor Property in the Designer on the parent Form.
Then, go to BUILD -> REBUILD SOLUTION.

This should also work in older versions of Visual Studio.

EDIT:
For Buttons, you need to Handle the Resize event, as other answers have suggested.

凶凌 2024-10-23 21:57:32

我有VS 2012,它甚至包含继承的表单,但我有同样的问题,无论我自己继承它还是使用模板......锚点出错,位置变化成倍增加,就像我只有表单一样,它会移动 1px 为 1px,如果我还有一个面板,它会移动 2 为 1px,如果我有 2 个面板,它会移动 3...我没有测量它,但它看起来像那样...


有点像答案:

一分钟前,我测试了一些东西,我将所有嵌套容器的修饰符设置为可访问的东西,然后子窗体生成更多代码,运行时是正确的,但现在设计器在每次编译后,将我的控件重新定位在窗体,所以关于这一点,我还在子窗体中添加了另一个面板,并将其设置为停靠模式,然后将我的控件锚定到它,然后它修复了,以前甚至锚定都出错了......

I'm having VS 2012, it even contain inherited forms, but i have same issue, no matter if i inherit it my self or use template... the anchor goes wrong, and the position change multiplied, like if i have only form, it goes 1px for 1px, if i have also a panel, it move 2 for 1px, if i have 2 panel it move 3... i didn't measure it, but it look like, like that...


Kinda An Answer:

A minute ago, i test some thing, i set modifier of all nested container, to some thing accessible, then the child form generate more code, run time was correct, but now the designer after each compile, repositioned my controls inside the form, so regarding that, i also add another panel in child form, and set it to dock mode, and then anchor my control to it, then it fixed, previously even anchoring went wrong...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文