0

我创建了一个自定义表单(FormBorderStyle = FormBorderStyle.None)。

我使用自己的自定义标题按钮(关闭、最大化...)在顶部绘制自己的标题栏。

现在我唯一的问题是向该表单添加普通用户控件。如果我给这些控件一个位置,这些位置是相对于窗体的顶部(包括标题栏)的。

我使用“new”关键字覆盖了默认的 ClientSize 和 ClientRectangle,这允许我对其进行调整(从而从中删除标题栏)。

这似乎不起作用,我无法弄清楚如何在不“破解” ControlAdded 事件(仍然是错误的)的情况下正确执行此操作。

    protected override void OnControlAdded(ControlEventArgs e)
    {
        base.OnControlAdded(e);
        if (e.Control.GetType() != typeof(VlufiCaptionButton /* Caption buttons: close, minimize & maximize, should not be included */))
        {
            e.Control.Location = new Point(e.Control.Location.X + ClientRectangle.X, e.Control.Location.Y + ClientRectangle.Y);
            e.Control.LocationChanged += Control_LocationChanged;
        }
    }
    private void Control_LocationChanged(object sender, EventArgs e)
    {
        if (!childControlLocationChangedHandled)
        {
            System.Diagnostics.Debug.WriteLine("changing");
            Control cControl = (Control)sender;
            childControlLocationChangedHandled = true;
            cControl.Location = new Point(cControl.Location.X + ClientRectangle.X, cControl.Location.Y + ClientRectangle.Y);
        }
        else
            childControlLocationChangedHandled = false;
    }

这是我目前使用的代码,但它非常棒,而且我的自定义绘制边框仍然存在其他问题。

有人知道我应该如何正确处理这个吗?

我找到了一个不错的解决方案:我在表单中添加了一个 ContainerControl,并根据表单对其进行定位和调整大小,然后每当向表单添加控件时,都应该将它添加到 ContainerControl。仍然不是一个合适的解决方案,但它是迄今为止最好的解决方案。

如果有人提出另一种解决方案,我仍然会很感激。

4

2 回答 2

0

毕竟,我终于找到了一个可行且非常好的解决方案。

我所做的是使用我自己的自定义 ControlCollection 覆盖我的自定义表单的 Controls 属性。

所以这就是我在自定义表单中得到的:

public Control.ControlCollection RealControls
{
    get
    {
        return base.Controls;
    }
}
public new CustomControlCollection Controls { get; private set; }

public ContainerControl ControlContainer { get; set; }

这是自定义的 ControlCollection:

public class CustomControlCollection 
{
    public VlufiForm Owner { get; private set; }
    public CustomControlCollection (VlufiForm pOwner)
    {
        Owner = pOwner;
    }
    public void Add(Control c)
    {
        Add(c, false);
    }
    public int Count
    {
        get
        {
            return Owner.ControlContainer.Controls.Count;
        }
    }
    public Control this[int index]
    {
        get
        {
            return Owner.ControlContainer.Controls[index];
        }
    }
    public void Add(Control c, bool isUsable)
    {
        if (isUsable)
            Owner.RealControls.Add(c);
        else
            Owner.ControlContainer.Controls.Add(c);
    }
    public void SetChildIndex(Control c, int nIndex)
    {
        Owner.ControlContainer.Controls.SetChildIndex(c, nIndex);
    }
}

这只是一个示例自定义控件集合,您可以在其中添加更多方法(从而更多地继承 ControlCollection)。我还没有在这个系统中发现任何错误,目前它运行良好。

编辑:发现一个错误,如果您在 Visual Studio 的设计器模式中停靠一个控件,它将停靠在整个表单中,但运行时不会出现。

于 2013-05-18T20:33:33.693 回答
0

详细阅读评论:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication1
{
    public partial class Form1 : Form
    {
        int dy = 0;
        public Form1()
        {
            InitializeComponent();
            //i add a panel to top form
            //( for simulating your caption bar) and get its height
            dy = panel1.Height; //for yours its your caption bar height
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //adding button control between form top and panel end area
            //( simulate in your caption bar )
            Button btn = new Button();
            btn.Location = new Point(panel1.Location.X+40,panel1.Location.Y+10);
            btn.Text = "Salam";
            this.Controls.Add(btn);
        }
        //in control added event i add dy ( height of ignored area) to control Location
        private void Form1_ControlAdded(object sender, ControlEventArgs e)
        {
            e.Control.Location = new Point(e.Control.Location.X, e.Control.Location.Y + dy);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}
于 2013-04-20T19:56:53.840 回答