C# 在C中重写派生标签控件的自动大小#

C# 在C中重写派生标签控件的自动大小#,c#,custom-controls,overriding,label,autosize,C#,Custom Controls,Overriding,Label,Autosize,我正在尝试扩展System.Windows.Forms.Label类以支持垂直绘制的文本。为此,我创建了一个名为MyLabelOrientation的新属性,用户可以将其设置为水平或垂直。当用户更改此设置时,将交换“宽度”和“高度”的值,以将控件调整为新方向。最后,我重写OnPaint函数来绘制标签 我还想扩展此控件的“自动调整大小”属性,以便我的标签将自动调整大小以适应其包含的文本。对于水平方向,基本功能为我实现了这一点。对于垂直方向,我创建了一个图形对象,并将控件的高度设置为Graphics

我正在尝试扩展System.Windows.Forms.Label类以支持垂直绘制的文本。为此,我创建了一个名为MyLabelOrientation的新属性,用户可以将其设置为水平或垂直。当用户更改此设置时,将交换“宽度”和“高度”的值,以将控件调整为新方向。最后,我重写OnPaint函数来绘制标签

我还想扩展此控件的“自动调整大小”属性,以便我的标签将自动调整大小以适应其包含的文本。对于水平方向,基本功能为我实现了这一点。对于垂直方向,我创建了一个图形对象,并将控件的高度设置为Graphics.MeasureString(文本,字体)返回的SizeF对象的宽度。您可以在下面看到我正在使用的代码示例

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

public class MyLabel : Label
{
    public enum MyLabelOrientation {Horizontal, Vertical};
    protected MyLabelOrientation m_orientation = MyLabelOrientation.Horizontal;

    [Category("Appearance")]
    public virtual MyLabelOrientation Orientation
    {
        get { return m_orientation; }
        set
        {
            m_orientation = value;
            int temp = Height;
            Width = Height;
            Height = temp;
            Refresh();
        }
    }

    private Size ResizeLabel()
    {
        Graphics g = Graphics.FromHwnd(this.Handle);
        SizeF newSize = g.MeasureString(Text, Font);
        if (m_orientation == MyLabelOrientation.Horizontal)
            Width = (int)newSize.Width;
        else
            Height = (int)newSize.Width;
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        Brush textBrush = new SolidBrush(this.ForeColor);

        if (m_orientation == LabelOrientation.Vertical)
        {
            e.Graphics.TranslateTransform(Width, 0);
            e.Graphics.RotateTransform(90);
            e.Graphics.DrawString(Text, Font, textBrush, Padding.Left, Padding.Top);
        }
        else
        {
            base.OnPaint(e);
        }
    }
}

但是,将AutoSize设置为true似乎会阻止和/或覆盖对控件大小的任何更改。这意味着当我想要更改标签的方向时,我不能更改宽度或高度。我想知道是否可以覆盖此行为,以便测试是否设置了AutoSize,然后根据控件的方向调整控件的大小。

我以前没有这样做过,我相信理论上可以覆盖属性声明(通过
new
关键字)并在继续之前检查方向:

override public bool AutoSize
{
   set 
   {
      if( /* orientation is horizontal */ )
      {
          base.AutoSize = value;
      }
      else
      {
          // do what you need to do
      }    
   }    
}

如果您认为解决方案是覆盖
OnResize
本身:

protected override void OnResize(EventArgs e)
{
    if (AutoSize)
    {
        // Perform your own resizing logic
    }
    else
        OnResize(e);
}

我知道这是一个相当古老的问题,但我今天偶然发现了它,并想知道如何做同样的事情

我的解决方案是重写
GetPreferredSize(Size proposedSize)
方法。我使用了一个button类,除了文本之外还包含一个箭头,当然,使用AutoSize属性时没有考虑到这个箭头,所以我添加了额外的空间,它对我来说很好

考虑到改变方向或改变宽度和高度的问题,您可以完全改变计算首选尺寸的方式

public override Size GetPreferredSize(Size proposedSize)
{
    Size s = base.GetPreferredSize(proposedSize);
    if (AutoSize)
    {
        s.Width += 15;
    }
    return s;
}

AutoSize是一种虚拟财产。使用覆盖,而不是新的。@Hans:相应地更新;在发布之前,我没有检查它是否是虚拟的。我认为这不是基于问题的性质。谢谢。我以前尝试过这个解决方案,当您像这样覆盖AutoSize时,控件或多或少会忽略。自动调整大小可防止对宽度或高度进行任何更改,而不考虑源。我需要覆盖其他可能会查看自动调整大小设置并相应调整大小的内容。这太完美了。我想覆盖一个复选框控件,并绘制一个稍大的彩色复选框。因此,通过简单地计算我的复选框比股票大多少,并将其添加到宽度中,它每次都会设置正确的宽度。