使用边距以编程方式向面板添加自定义控件

时间:2017-09-29 08:30:38

标签: c# winforms custom-controls

您好我制作了一个带有相关标签的自定义文本框。 我有一个自定义表格。

当我在表单上拖动我的自定义文本框从工具箱中删除并设置它的属性时,我可以看到它的工作原理。但是,我想要做的是当我在我的自定义控件上时,我有一个TableLayoutPanel(有3行) 在行索引1(中间行)我想以编程方式添加我的自定义控件。

当我这样做时,文本标签就在文本框的其他地方。

我的代码和我的问题的图像如下:

MyCustomTextBox:

public class MyLbTextBox : TextBox
{       
    #region CustomProperties

    private Label AssociatedLabel = new Label();
    private string _myLbText;

    public string MyTextLabel
    {
        get => _myLbText;
        set
        {              
            _myLbText = value;              
            AssociatedLabel.Text = _myLbText ?? _myBindingField;
            Size s = TextRenderer.MeasureText(AssociatedLabel.Text, AssociatedLabel.Font);
            AssociatedLabel.Location =
                new Point(Location.X - s.Width - AssociatedLabel.Padding.Right, Location.Y);
            var MyMargin = this.Margin;
            MyMargin.Left = 100;
            this.Margin = MyMargin;
        }
    }


    #endregion

    private string _myBindingField;

    public string MyBindingField
    {
        get { return _myBindingField; }
        set
        {
            _myBindingField = value; 

        }
    }

    private MyJoins.MyExpressions _myExpression;

    public MyJoins.MyExpressions MyExpression
    {
        get => _myExpression;
        set => _myExpression = value;
    }

    public MyLbTextBox()
    {
        _myExpression = MyJoins.MyExpressions.Equals;
        ParentChanged += MyLbTextBox_ParentChanged;
        LocationChanged += MyLbTextBox_LocationChanged;
        Disposed += MyLbTextBox_Disposed;
    }

    private void MyLbTextBox_Disposed(object sender, EventArgs e)
    {
        AssociatedLabel.Dispose();
    }

    private void MyLbTextBox_LocationChanged(object sender, EventArgs e)
    {
        Size s = TextRenderer.MeasureText(AssociatedLabel.Text, AssociatedLabel.Font);
        AssociatedLabel.Location =
            new Point(Location.X - s.Width - AssociatedLabel.Padding.Right, Location.Y);
    }

    private void MyLbTextBox_ParentChanged(object sender, EventArgs e)
    {
        AutoAddAssociatedLabel();
    }

    private void AutoAddAssociatedLabel()
    {
        if (Parent == null) return;

        AssociatedLabel.Padding = new Padding(3);

        Size s = TextRenderer.MeasureText(AssociatedLabel.Text, AssociatedLabel.Font);
        AssociatedLabel.Location =
            new Point(Location.X - s.Width - AssociatedLabel.Padding.Right, Location.Y);

        Parent.Controls.Add(AssociatedLabel);
    }
}

enter image description here

顺便说一句,这就是我添加控件的方式:

enter image description here

通过属性网格添加我的控件

这就是我在屏幕上设置它们的方式

private void _mySearchFields_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (_mySearchFields == null) return;
        foreach (var searchField in _mySearchFields)
        {
            if (MySearchFieldsPanel.Contains(searchField.MyControl)) continue;
            MySearchFieldsPanel.Controls.Add(searchField.MyControl, 1, 0);               
        }
        var myHeight = MySearchFieldsPanel.Controls.Cast<Control>().Sum(variable => variable.Height);
        MyBdPanel.RowStyles[1].Height = myHeight + 40;
    }

我感谢任何帮助

1 个答案:

答案 0 :(得分:0)

这一行是所有问题的原因:

Parent.Controls.Add(AssociatedLabel);

如果要创建复合控件(composite =由多个 real 控件组成),这是个坏主意。这将导致您遇到的布局问题等等。

而是考虑:

  1. 利用UserControl创建合成。
  2. 创建自定义控件(与您一样),但不带更多控件。如果你需要标签 - 在OnPaint中将其作为文本绘制,同时分配一些空间:固定带边距,可调整某些属性或带有测量文本的动态。