如何在设计时立即更新自定义控件属性?

时间:2019-10-30 02:39:02

标签: c# visual-studio

我创建了一个自定义控件,该控件使用c#类库从面板控件继承,然后在表单中使用它。 在设计期间选择任何属性时,我的自定义控件不会更新! 如果我关闭表单并重新打开,它将发生更改!

我想在更改任何属性时更新控件吗?

这是我的自定义控制代码示例:

public class PersoCont  :Panel
    {
        private int borderSize = 2;
        private Color borderColor = Color.DarkRed;
        private bool isBorder = true;
        private int paddingTopTitle = 0;
        private int paddingBorder = 0;

        public int padding_TopTitle
        {
            get { return paddingTopTitle; }
            set { paddingTopTitle = value; Invalidate(); }
        }

        public int padding_border
        {
            get { return paddingBorder; }
            set { paddingBorder = value; Invalidate(); }
        }

        public int border_size
        {
            get { return borderSize; }
            set { borderSize = value; Invalidate(); }
        }

        public Color border_color
        {
            get { return borderColor; }
            set { borderColor = value; Invalidate(); }
        }

        public bool is_border
        {
            get { return isBorder; }
            set { isBorder = value; Invalidate(); }
        }

        public PersoCont()
        {

        }

        protected override void OnHandleCreated(EventArgs e)
        {
            if (this.Controls.Find("xlblTitle", true).Length == 0)
            {
                if (isBorder == true)
                {
                    Label lblUp = new Label();
                    lblUp.Text = "";
                    lblUp.AutoSize = false;
                    lblUp.BackColor = borderColor;
                    int lblUpWidth = this.Width - (2 * paddingBorder) - (2 * borderSize);
                    lblUp.Size = new Size(lblUpWidth, borderSize);
                    lblUp.Location = new Point(borderSize + paddingBorder, paddingBorder);
                    lblUp.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right;

                    Label lblDown = new Label();
                    lblDown.Text = "";
                    lblDown.AutoSize = false;
                    lblDown.BackColor = borderColor;
                    lblDown.Size = new Size(lblUpWidth, borderSize);
                    int lblDownTop = this.Height - paddingBorder - borderSize;
                    lblDown.Location = new Point(borderSize + paddingBorder, lblDownTop);
                    lblDown.Anchor = AnchorStyles.Left | AnchorStyles.Bottom | AnchorStyles.Right;

                    Label lblLeft = new Label();
                    lblLeft.Text = "";
                    lblLeft.AutoSize = false;
                    lblLeft.BackColor = borderColor;
                    int lblLeftHeight = this.Height - (2 * paddingBorder);
                    lblLeft.Size =new Size(borderSize,lblLeftHeight);
                    lblLeft.Location = new Point(paddingBorder, paddingBorder);
                    lblLeft.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Bottom;

                    Label lblRight = new Label();
                    lblRight.Text = "";
                    lblRight.AutoSize = false;
                    lblRight.BackColor = borderColor;
                    lblRight.Size = new Size(borderSize, lblLeftHeight);
                    int lblRightLeft = this.Width - paddingBorder - borderSize;
                    lblRight.Location = new Point(lblRightLeft, paddingBorder);
                    lblRight.Anchor = AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Bottom;

                    this.Controls.Add(lblUp);
                    this.Controls.Add(lblDown);
                    this.Controls.Add(lblLeft);
                    this.Controls.Add(lblRight);
                }
            }
            base.OnHandleCreated(e);
        }
    }

3 个答案:

答案 0 :(得分:0)

使用Refresh代替Invalidate,因为这最后一个标记仅标记需要重涂的系统,而无需这样做,请Refresh进行。

https://docs.microsoft.com/dotnet/api/system.windows.forms.control.refresh

https://docs.microsoft.com/dotnet/api/system.windows.forms.control.update

只有在必要时,您可以在调用refresh之前测试内部值是否已更改:

public int padding_TopTitle
{
  get 
  { 
    return paddingTopTitle; 
  }
  set 
  { 
    if ( paddingTopTitle != value )
    {
      paddingTopTitle = value; 
      Refresh(); 
    }
  }
}

您可以考虑使用Framework Design GuidelinesC# Naming Conventions

例如:

public int PaddingTopTitle
{
  get 
  { 
    return paddingTopTitle; 
  }
  set 
  { 
    if ( paddingTopTitle != value )
    {
      paddingTopTitle = value; 
      Refresh(); 
    }
  }
}

或者:

public int PaddingTopTitle
{
  get 
  { 
    return _PaddingTopTitle; 
  }
  set 
  { 
    if ( _PaddingTopTitle != value )
    {
      _PaddingTopTitle = value; 
      Refresh(); 
    }
  }
}

我个人更喜欢使用_PaddingTopTitle(或_paddingTopTitle)作为属性的私有字段,因为paddingTopTitle既用作方法参数又用作局部变量。

因此,您可能有:BorderSize_BorderSize(或_borderSize)。

答案 1 :(得分:0)

您可以尝试以下代码来重写面板控件以获得所需的内容。

  public  class MyPanel : Panel
    {
        private Color colorBorder = Color.Transparent;


        public MyPanel()
            : base()
        {
            this.SetStyle(ControlStyles.UserPaint, true);

        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            e.Graphics.DrawRectangle(
                new Pen(
                    new SolidBrush(colorBorder), 6),
                    e.ClipRectangle);
        }

        public Color BorderColor
        {
            get
            {
                return colorBorder;
            }
            set
            {
                colorBorder = value;
            }
        }
    }

结果: enter image description here

也许它有点尴尬,因为它只有在单击表单设计器之后才能起作用。

答案 2 :(得分:0)

谢谢大家的帮助。

首先,我使用了OnPaint事件,但实际上我不喜欢它,因为它触发了很多次(我不知道为什么!)

我的问题如下解决:

我创建了一个简单的人员私有方法,该方法可以根据所有属性刷新图形数据,并且一切正常!

public class PersoCont2 : Panel
{
    Label lblUp = null;

    bool isBorder;
    Color borderColor;

    public bool is_border
    {
        get { return isBorder; }
        set { isBorder = value; Rearrange( ); }
    }

    public Color border_color
    {
        get { return borderColor; }
        set { borderColor = value; Rearrange( ); }
    }

    protected override void OnHandleCreated(EventArgs e)
        {
            Rearrange();
        }

    private void Rearrange( )
    {
        if( lblUp != null )
        {
            Controls.Remove( lblUp );
            lblUp = null;
        }
        if( is_border )
        {
            lblUp = new Label( );
            lblUp.BackColor = borderColor;
            // TODO: set properties
            // . . .
            lblUp.Location = new Point( 10, 10 );
            Controls.Add( lblUp );
        }
    }
}