【发布时间】:2011-06-25 16:47:05
【问题描述】:
我需要一个解决方法来解决继承的库存 Windows 窗体上的面板的错误行为。我有几个按钮应该锚定在面板的右下角,但是它们的位置以我无法在继承的表单上预测的方式变化。我已经尝试了 Dock 和 Anchor 属性的各种组合,但到目前为止还没有使按钮显示在它们应该显示的位置。所有控件都标记为受保护。
base 表单本身的行为是正确的。错误行为仅发生在 inherited 表单上;按钮没有锚定到它们的父面板。
如果我将按钮锚定在左上角,我可以将继承的表单调整得更大,最终按钮将在基本表单大小之外的某个位置被发现。如果我将按钮固定在右下角,我将无法使表单大到足以露出按钮。
我尝试创建一个继承 Panel 和 GroupBox 的自定义面板,但它们的工作方式没有任何不同。我有同样的运气将按钮直接放在表单上,没有容器。
我想要的:一个可调整大小的表单底部的面板,我的按钮在它的右下角。表单的其余部分应该是 DataGridView 的可调整大小区域(我已经解决了这个问题的继承和对接问题>:-/)无论窗口大小如何,按钮都应该始终位于右下角。我不想调整按钮的大小。
如果我必须自己调整控件的大小,我愿意这样做。但如果框架能正确地做到这一点,我只需要学习如何正确使用它,我更喜欢教育。
我发现这个链接似乎描述了类似的不当行为:How to stop buttons from moving in inherited 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;
继承的表单(调整大小以适合我的数据内容)
//
// 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 文件中的代码仍然正确,但按钮属性发生了变化。在从上面继承的表单中,refreshButton 和 saveButton 的设计器的 Location 属性是 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);
}
【问题讨论】:
-
VS2010是否出现问题?如果没有,请尝试使用 Express Edition。
-
谢谢,但我使用的是 VS2005 Professional。升级不是一个负担得起的选择。
-
了解它是否已在更高版本中修复会很有用。
-
V2013 中的相同症状,通过左侧、底部锚点而不是右侧、底部锚点“解决”...
标签: c# winforms inheritance controls anchor