ファイル名を示すラベルがあります。設計のために、ラベルのAutoSize
をFalse
に設定する必要がありました。
そのため、ファイル名のテキストがラベルサイズより長くなった場合、写真のように切り取られました。
label1.Size = new Size(200, 32);
label1.AutoSize = false;
テキストがラベルサイズよりも長い場合、ラベルサイズに合わせてテキストのサイズを自動的に変更するにはどうすればよいですか?
以下のコードスニペットを使用できます。システムは、テキストサイズに基づいてラベルのフォントを計算するためにいくつかのループを必要とします。
while(label1.Width < System.Windows.Forms.TextRenderer.MeasureText(label1.Text,
new Font(label1.Font.FontFamily, label1.Font.Size, label1.Font.Style)).Width)
{
label1.Font = new Font(label1.Font.FontFamily, label1.Font.Size - 0.5f, label1.Font.Style);
}
ラベルのスケーリング
private void scaleFont(Label lab)
{
Image fakeImage = new Bitmap(1, 1); //As we cannot use CreateGraphics() in a class library, so the fake image is used to load the Graphics.
Graphics graphics = Graphics.FromImage(fakeImage);
SizeF extent = graphics.MeasureString(lab.Text, lab.Font);
float hRatio = lab.Height / extent.Height;
float wRatio = lab.Width / extent.Width;
float ratio = (hRatio < wRatio) ? hRatio : wRatio;
float newSize = lab.Font.Size * ratio;
lab.Font = new Font(lab.Font.FontFamily, newSize, lab.Font.Style);
}
@ToolmakerSteveがコメントで指摘したTextRenderer Approach
private void ScaleFont(Label lab)
{
SizeF extent = TextRenderer.MeasureText(lab.Text, lab.Font);
float hRatio = lab.Height / extent.Height;
float wRatio = lab.Width / extent.Width;
float ratio = (hRatio < wRatio) ? hRatio : wRatio;
float newSize = lab.Font.Size * ratio;
lab.Font = new Font(lab.Font.FontFamily, newSize, lab.Font.Style);
}
@brgernerが提供する article に基づいて、ここで代替実装を提供します。回答としてマークされた実装は、以下の実装ほど効率的でも完全でもないためです。
public class FontWizard
{
public static Font FlexFont(Graphics g, float minFontSize, float maxFontSize, Size layoutSize, string s, Font f, out SizeF extent)
{
if (maxFontSize == minFontSize)
f = new Font(f.FontFamily, minFontSize, f.Style);
extent = g.MeasureString(s, f);
if (maxFontSize <= minFontSize)
return f;
float hRatio = layoutSize.Height / extent.Height;
float wRatio = layoutSize.Width / extent.Width;
float ratio = (hRatio < wRatio) ? hRatio : wRatio;
float newSize = f.Size * ratio;
if (newSize < minFontSize)
newSize = minFontSize;
else if (newSize > maxFontSize)
newSize = maxFontSize;
f = new Font(f.FontFamily, newSize, f.Style);
extent = g.MeasureString(s, f);
return f;
}
public static void OnPaint(object sender, PaintEventArgs e, string text)
{
var control = sender as Control;
if (control == null)
return;
control.Text = string.Empty; //delete old stuff
var rectangle = control.ClientRectangle;
using (Font f = new System.Drawing.Font("Microsoft Sans Serif", 20.25f, FontStyle.Bold))
{
SizeF size;
using (Font f2 = FontWizard.FlexFont(e.Graphics, 5, 50, rectangle.Size, text, f, out size))
{
PointF p = new PointF((rectangle.Width - size.Width) / 2, (rectangle.Height - size.Height) / 2);
e.Graphics.DrawString(text, f2, Brushes.Black, p);
}
}
}
}
および使用法:
val label = new Label();
label.Paint += (sender, e) => FontWizard.OnPaint(sender, e, text);
@ bnguyen82からのインスピレーションで、私はずっとうまくいくものを思いつきました。
public static void ScaleLabel(Label label, float stepSize = 0.5f)
{
//decrease font size if text is wider or higher than label
while (lblTextSize() is Size s && s.Width > label.Width || s.Height > label.Height)
{
label.Font = new Font(label.Font.FontFamily, label.Font.Size - stepSize, label.Font.Style);
}
//increase font size if label width is bigger than text size
while (label.Width > lblTextSize().Width)
{
var font = new Font(label.Font.FontFamily, label.Font.Size + stepSize, label.Font.Style);
var nextSize = TextRenderer.MeasureText(label.Text, font);
//dont make text width or hight bigger than label
if (nextSize.Width > label.Width || nextSize.Height > label.Height)
break;
label.Font = font;
}
Size lblTextSize() => TextRenderer.MeasureText(label.Text,
new Font(label.Font.FontFamily, label.Font.Size, label.Font.Style));
}
PS:これを機能させるには、ラベルにAutoSize = false
およびdocked
またはanchored
のいずれか。
私は、次の重み付きスケーリングトリックを使用して、適切なフィットを提供します。つまり、高さの調整と幅の調整との間で重み付けのトレードオフが行われます。 VB .netですが、C#に簡単に翻訳できると思います。
Function shrinkFontToFit(f As Font, text As String, requiredsize As SizeF) As Font
Dim actualsize As SizeF = TextRenderer.MeasureText(text, f)
Return New Font(f.FontFamily, f.Size * (requiredsize.Width + requiredsize.Height ) _
/ (actualsize.Width + actualsize.Height), f.Style, GraphicsUnit.Pixel)
End Function