C#.NET Winforms:是否可以覆盖 Label.Autosize?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25200/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-01 09:14:18  来源:igfitidea点击:

C#.NET Winforms: Is it possible to override Label.Autosize?

提问by Martin Marconcini

I don't like the AutoSize property of the Label control. I have a custom Label that draws a fancy rounded border among other things. I'm placing a AutoSize = falsein my constructor, however, when I place it in design mode, the property always is True.

我不喜欢 Label 控件的 AutoSize 属性。我有一个自定义 Label 可以绘制花哨的圆形边框等。我将 aAutoSize = false放在我的构造函数中,但是,当我将它置于设计模式时,该属性始终为 True。

I have overridden other properties with success but this one is happily ignoring me. Does anybody has a clue if this is "by MS design"?

我已经成功地覆盖了其他属性,但这个属性很高兴地忽略了我。如果这是“由 MS 设计”,有人知道吗?

Here's the full source code of my Label in case anyone is interested.

这是我的标签的完整源代码,以防有人感兴趣。

using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace Dentactil.UI.WinControls
{
    [DefaultProperty("TextString")]
    [DefaultEvent("TextClick")]
    public partial class RoundedLabel : UserControl
    {
        private static readonly Color DEFAULT_BORDER_COLOR = Color.FromArgb( 132, 100, 161 );
        private const float DEFAULT_BORDER_WIDTH = 2.0F;
        private const int DEFAULT_ROUNDED_WIDTH = 16;
        private const int DEFAULT_ROUNDED_HEIGHT = 12;

        private Color mBorderColor = DEFAULT_BORDER_COLOR;
        private float mBorderWidth = DEFAULT_BORDER_WIDTH;
        private int mRoundedWidth = DEFAULT_ROUNDED_WIDTH;
        private int mRoundedHeight = DEFAULT_ROUNDED_HEIGHT;

        public event EventHandler TextClick;

        private Padding mPadding = new Padding(8);

        public RoundedLabel()
        {
            InitializeComponent();
        }

        public Cursor TextCursor
        {
            get { return lblText.Cursor; }
            set { lblText.Cursor = value; }
        }

        public Padding TextPadding
        {
            get { return mPadding; }
            set
            {
                mPadding = value;
                UpdateInternalBounds();
            }
        }

        public ContentAlignment TextAlign
        {
            get { return lblText.TextAlign; }
            set { lblText.TextAlign = value; }
        }

        public string TextString
        {
            get { return lblText.Text; }
            set { lblText.Text = value; }
        }

        public override Font Font
        {
            get { return base.Font; }
            set
            {
                base.Font = value;
                lblText.Font = value;
            }
        }

        public override Color ForeColor
        {
            get { return base.ForeColor; }
            set
            {
                base.ForeColor = value;
                lblText.ForeColor = value;
            }
        }

        public Color BorderColor
        {
            get { return mBorderColor; }
            set
            {
                mBorderColor = value;
                Invalidate();
            }
        }

        [DefaultValue(DEFAULT_BORDER_WIDTH)]
        public float BorderWidth
        {
            get { return mBorderWidth; }
            set
            {
                mBorderWidth = value;
                Invalidate();
            }
        }

        [DefaultValue(DEFAULT_ROUNDED_WIDTH)]
        public int RoundedWidth
        {
            get { return mRoundedWidth; }
            set
            {
                mRoundedWidth = value;
                Invalidate();
            }
        }

        [DefaultValue(DEFAULT_ROUNDED_HEIGHT)]
        public int RoundedHeight
        {
            get { return mRoundedHeight; }
            set
            {
                mRoundedHeight = value;
                Invalidate();
            }
        }

        private void UpdateInternalBounds()
        {
            lblText.Left = mPadding.Left;
            lblText.Top = mPadding.Top;

            int width = Width - mPadding.Right - mPadding.Left;
            lblText.Width = width > 0 ? width : 0;

            int heigth = Height - mPadding.Bottom - mPadding.Top;
            lblText.Height = heigth > 0 ? heigth : 0;
        }

        protected override void OnLoad(EventArgs e)
        {
            UpdateInternalBounds();
            base.OnLoad(e);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            SmoothingMode smoothingMode = e.Graphics.SmoothingMode;
            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

            int roundedWidth = RoundedWidth > (Width - 1)/2 ? (Width - 1)/2 : RoundedWidth;
            int roundedHeight = RoundedHeight > (Height - 1)/2 ? (Height - 1)/2 : RoundedHeight;

            GraphicsPath path = new GraphicsPath();
            path.AddLine(0, roundedHeight, 0, Height - 1 - roundedHeight);
            path.AddArc(new RectangleF(0, Height - 1 - 2*roundedHeight, 2*roundedWidth, 2*roundedHeight), 180, -90);
            path.AddLine(roundedWidth, Height - 1, Width - 1 - 2*roundedWidth, Height - 1);
            path.AddArc(new RectangleF(Width - 1 - 2*roundedWidth, Height - 1 - 2*roundedHeight, 2*roundedWidth, 2*roundedHeight), 90, -90);
            path.AddLine(Width - 1, Height - 1 - roundedHeight, Width - 1, roundedHeight);
            path.AddArc(new RectangleF(Width - 1 - 2*roundedWidth, 0, 2*roundedWidth, 2*roundedHeight), 0, -90);
            path.AddLine(Width - 1 - roundedWidth, 0, roundedWidth, 0);
            path.AddArc(new RectangleF(0, 0, 2*roundedWidth, 2*roundedHeight), -90, -90);

            e.Graphics.DrawPath(new Pen(new SolidBrush(BorderColor), BorderWidth), path);

            e.Graphics.SmoothingMode = smoothingMode;
            base.OnPaint(e);
        }

        protected override void OnResize(EventArgs e)
        {
            UpdateInternalBounds();
            base.OnResize(e);
        }

        private void lblText_Click(object sender, EventArgs e)
        {
            if (TextClick != null)
            {
                TextClick(this, e);
            }
        }
    }
}

(there are some issues with Stack Overflow's markup and the Underscore, but it's easy to follow the code).

(Stack Overflow 的标记和下划线存在一些问题,但很容易遵循代码)。



I have actually removed that override some time ago when I saw that it wasn't working. I'll add it again now and test. Basically I want to replace the Label with some new label called: IWillNotAutoSizeLabel ;)

前段时间当我看到它不起作用时,我实际上已经删除了该覆盖。我现在再次添加并测试。基本上我想用一些名为的新标签替换标签: IWillNotAutoSizeLabel ;)

I basically hate the autosize property "on by default".

我基本上讨厌“默认情况下”的 autosize 属性。

采纳答案by Matt Hamilton

I've seen similar behaviour when setting certain properties of controls in the constructor of the form itself. They seem to revert back to their design-time defaults.

在表单本身的构造函数中设置控件的某些属性时,我已经看到了类似的行为。他们似乎恢复到设计时的默认设置。

I notice you're already overriding the OnLoad method. Have you tried setting AutoSize = false there? Or are you mainly concerned with providing a defaultvalue of false?

我注意到您已经覆盖了 OnLoad 方法。你试过在那里设置 AutoSize = false 吗?或者您主要关心的是提供默认值 false 吗?

回答by TheSmurf

Your problem could be that you're not actually overriding Autosize in your code (ie, in the same way that you're overriding Font or ForeColor).

您的问题可能是您实际上并未在代码中覆盖 Autosize(即,与覆盖 Font 或 ForeColor 的方式相同)。

回答by ESRogs

I don't see this.AutoSize = falsein your constructor. Your class is marked as partial -- perhaps you have a constructor in another file with that line. The visual studio designer will call that parameterless constructor you've got there.

this.AutoSize = false在你的构造函数中没有看到。你的类被标记为部分——也许你在另一个文件中有一个带有该行的构造函数。Visual Studio 设计器将调用您在那里获得的无参数构造函数。

回答by iard68

I spent a lot of time with it and this finally works! (my code is vb.net but is simple to convert it)

我花了很多时间,这终于奏效了!(我的代码是 vb.net 但转换起来很简单)

Private _Autosize As Boolean 

Public Sub New()
    _Autosize=False
End Sub

Public Overrides Property AutoSize() As Boolean
    Get
        Return MyBase.AutoSize
    End Get

    Set(ByVal Value As Boolean)
        If _Autosize <> Value And _Autosize = False Then
            MyBase.AutoSize = False
            _Autosize = Value
        Else
            MyBase.AutoSize = Value
        End If
    End Set
End Property