Windows 将多个控件合二为一
Windows Forms Multiple Controls In One
想请教一下。我在 windows 表单编程方面没有足够的经验,所以我不知道处理这个任务的合适方法是什么。
我目前正在用四个面板创建一个矩形。 (这些矩形不代表下面的代码,它们使用不同的大小)
private System.Windows.Forms.Panel rectangleLeftVertical;
private System.Windows.Forms.Panel rectangleRightVertical;
private System.Windows.Forms.Panel rectangleTopHorizontal;
private System.Windows.Forms.Panel rectangleBottomHorizontal;
// ...
this.rectangleLeftVertical.Location = new System.Drawing.Point(100, 100);
this.rectangleLeftVertical.Size = new System.Drawing.Size(3, 100);
this.rectangleRightVertical.Location = new System.Drawing.Point(200, 100);
this.rectangleRightVertical.Size = new System.Drawing.Size(3, 100);
this.rectangleTopHorizontal.Location = new System.Drawing.Point(100, 100);
this.rectangleTopHorizontal.Size = new System.Drawing.Size(100, 3);
this.rectangleBottomHorizontal.Location = new System.Drawing.Point(100, 200);
this.rectangleBottomHorizontal.Size = new System.Drawing.Size(103, 3);
它完全按照我想要的方式工作,我只想将所有内容封装到一个 自定义 Windows 控件 中。
自定义组件大小当然应该调整面板的大小。它还将有一个 属性 指示边框大小。
我不想改变任何东西,我不想做不同的绘图(使用 graphics.paint 解决方案)。它不适合我的用例。
我尝试使用 UserControl,但是它不合适,因为它绘制了矩形的整个内部 - 这是我试图避免的。
如果它也可以在 Windows Forms Designer 中使用,那就更好了 - 但这是非常不必要的。不过那真的很不错。
你们建议我如何解决这个问题?任何帮助将非常感激。这可能不是一个难题,我只是缺乏经验。谢谢!
您可以通过创建一个表示您想要 keep/discard 的表单区域的 GraphicsPath 对象来实现此目的。从覆盖整个表单的矩形开始,然后移除面板的中间,只留下边框。然后从该 GraphicsPath 构建一个区域并将其分配给表单的区域 属性。这将导致表单仅存在于边框所在的位置。从 GraphicsPath 中删除的中间区域实际上将不存在于您的表单中,因此叠加层下方的任何内容都会一直显示。
这里有一个简单的例子,它制作了一个四窗格“window”,可以通过窗格的边框来回拖动:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.TopMost = true;
this.BackColor = Color.Red; // just so you can see it better
this.FormBorderStyle = FormBorderStyle.None;
}
private void Form1_Shown(object sender, EventArgs e)
{
GraphicsPath path = new GraphicsPath();
// add the main rectangle:
path.AddRectangle(new Rectangle(new Point(0, 0), this.Size));
// punch some holes in our main rectangle
// this will make a standard "windowpane" with four panes
// and a border width of ten pixels
Size sz = new Size((this.Width - (3 * 10))/2, (this.Height - (3 * 10))/2);
path.FillMode = FillMode.Alternate;
path.AddRectangle(new Rectangle(new Point(10, 10), sz));
path.AddRectangle(new Rectangle(new Point(20 + sz.Width, 10), sz));
path.AddRectangle(new Rectangle(new Point(10, 20 + sz.Height), sz));
path.AddRectangle(new Rectangle(new Point(20 + sz.Width, 20 + sz.Height), sz));
// build a region from our path and set the forms region to that:
this.Region = new Region(path);
}
public const int HTCAPTION = 0x2;
public const int WM_NCHITTEST = 0x84;
public const int HTCLIENT = 1;
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == WM_NCHITTEST)
{
if (m.Result.ToInt32() == HTCLIENT)
m.Result = (IntPtr)HTCAPTION;
}
}
}
它的例子 运行 在我编辑它的时候在这个页面的顶部:
如果您的叠加层可以调整大小and/or,只需重建一个新的 GraphicsPath,更改矩形和 re-assign 从新的 GraphicsPath 构建的区域。
您也可以删除主窗体的 .Opacity
,这样您就可以部分看到您的边框。
想请教一下。我在 windows 表单编程方面没有足够的经验,所以我不知道处理这个任务的合适方法是什么。
我目前正在用四个面板创建一个矩形。 (这些矩形不代表下面的代码,它们使用不同的大小)
private System.Windows.Forms.Panel rectangleLeftVertical;
private System.Windows.Forms.Panel rectangleRightVertical;
private System.Windows.Forms.Panel rectangleTopHorizontal;
private System.Windows.Forms.Panel rectangleBottomHorizontal;
// ...
this.rectangleLeftVertical.Location = new System.Drawing.Point(100, 100);
this.rectangleLeftVertical.Size = new System.Drawing.Size(3, 100);
this.rectangleRightVertical.Location = new System.Drawing.Point(200, 100);
this.rectangleRightVertical.Size = new System.Drawing.Size(3, 100);
this.rectangleTopHorizontal.Location = new System.Drawing.Point(100, 100);
this.rectangleTopHorizontal.Size = new System.Drawing.Size(100, 3);
this.rectangleBottomHorizontal.Location = new System.Drawing.Point(100, 200);
this.rectangleBottomHorizontal.Size = new System.Drawing.Size(103, 3);
它完全按照我想要的方式工作,我只想将所有内容封装到一个 自定义 Windows 控件 中。 自定义组件大小当然应该调整面板的大小。它还将有一个 属性 指示边框大小。
我不想改变任何东西,我不想做不同的绘图(使用 graphics.paint 解决方案)。它不适合我的用例。
我尝试使用 UserControl,但是它不合适,因为它绘制了矩形的整个内部 - 这是我试图避免的。
如果它也可以在 Windows Forms Designer 中使用,那就更好了 - 但这是非常不必要的。不过那真的很不错。
你们建议我如何解决这个问题?任何帮助将非常感激。这可能不是一个难题,我只是缺乏经验。谢谢!
您可以通过创建一个表示您想要 keep/discard 的表单区域的 GraphicsPath 对象来实现此目的。从覆盖整个表单的矩形开始,然后移除面板的中间,只留下边框。然后从该 GraphicsPath 构建一个区域并将其分配给表单的区域 属性。这将导致表单仅存在于边框所在的位置。从 GraphicsPath 中删除的中间区域实际上将不存在于您的表单中,因此叠加层下方的任何内容都会一直显示。
这里有一个简单的例子,它制作了一个四窗格“window”,可以通过窗格的边框来回拖动:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.TopMost = true;
this.BackColor = Color.Red; // just so you can see it better
this.FormBorderStyle = FormBorderStyle.None;
}
private void Form1_Shown(object sender, EventArgs e)
{
GraphicsPath path = new GraphicsPath();
// add the main rectangle:
path.AddRectangle(new Rectangle(new Point(0, 0), this.Size));
// punch some holes in our main rectangle
// this will make a standard "windowpane" with four panes
// and a border width of ten pixels
Size sz = new Size((this.Width - (3 * 10))/2, (this.Height - (3 * 10))/2);
path.FillMode = FillMode.Alternate;
path.AddRectangle(new Rectangle(new Point(10, 10), sz));
path.AddRectangle(new Rectangle(new Point(20 + sz.Width, 10), sz));
path.AddRectangle(new Rectangle(new Point(10, 20 + sz.Height), sz));
path.AddRectangle(new Rectangle(new Point(20 + sz.Width, 20 + sz.Height), sz));
// build a region from our path and set the forms region to that:
this.Region = new Region(path);
}
public const int HTCAPTION = 0x2;
public const int WM_NCHITTEST = 0x84;
public const int HTCLIENT = 1;
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == WM_NCHITTEST)
{
if (m.Result.ToInt32() == HTCLIENT)
m.Result = (IntPtr)HTCAPTION;
}
}
}
它的例子 运行 在我编辑它的时候在这个页面的顶部:
如果您的叠加层可以调整大小and/or,只需重建一个新的 GraphicsPath,更改矩形和 re-assign 从新的 GraphicsPath 构建的区域。
您也可以删除主窗体的 .Opacity
,这样您就可以部分看到您的边框。