将控件添加到自定义窗体

时间:2013-04-20 19:39:19

标签: c# winforms custom-controls

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

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

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

我覆盖默认的ClientSize& ClientRectangle使用'new'关键字,允许我调整它(从而删除标题栏)。

这似乎不起作用,如果没有“黑客攻击”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中。仍然不是一个合适的解决方案,但它是目前为止最好的解决方案。

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

2 个答案:

答案 0 :(得分: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();
        }
    }
}

答案 1 :(得分:0)

好吧,毕竟我终于找到了一个有效的解决方案。

我所做的是使用我自己的自定义ControlCollection覆盖自定义Form的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的Designer模式中停靠一个控件,它将停靠在整个表单中,这在运行时不会出现。