为什么TextRenderer没有在Usercontrol中绘制Wingdings字体?

时间:2017-10-13 13:25:45

标签: c# winforms user-controls

用一个例子解释我的问题比用文字解释更容易。

这是我的UserControl1代码:

namespace WindowsFormsApplication1 {

    public partial class UserControl1 : UserControl {

        public UserControl1() {
            InitializeComponent();
        }

        private void UserControl1_Paint(object sender, PaintEventArgs e) {
            Graphics g = CreateGraphics();
            TextRenderer.DrawText(g, "à", new Font("Wingdings", 12), new Point(10, 10), Color.Black);
            TextRenderer.DrawText(g, "à", Font, new Point(30, 10), Color.Black);
            TextRenderer.DrawText(g, "à", new Font(Font.Name, Font.Size), new Point(50, 10), Color.Black);
            g.Dispose();
        }
    }
}

我将此控件添加到窗体并将其Font属性设置为Wingdings 12.
第二个TextRenderer行不会绘制右箭头,而只是“à” 第三行确实绘制了一个箭头,与第一行完全相同。

也许我错过了一些设置,有人可以解释一下吗?

2 个答案:

答案 0 :(得分:2)

您在第一个DrawText()函数调用中创建了Wingdings Font对象,但是您没有保存该对象以用于第二个和第三个DrawText()函数调用,因此它们将恢复为到默认字体。具体来说,他们正在使用this.Font对象,这是为UserControl设置的字体。

要解决此问题,您需要将Wingdings Font对象保存在变量中,然后在每次调用DrawText()时重复使用它。

此外,您不应该在Paint事件处理程序中调用CreateGraphics()函数。 Paint事件处理程序已经获取要绘制的Graphics对象作为PaintEventArgs的成员传递。这将更有效,也更简单,因为你不需要费心去处理它。

当你需要处理某些东西(比如Font对象)时,最好将它包装在using语句中。这样可以确保自动处理它,而不必担心自己或在发生异常时调用Dispose()。

因此,考虑到这些要点,您应该将代码重写为:

private void UserControl1_Paint(object sender, PaintEventArgs e) {
    using (Font f = new Font("Wingdings", 12)) {
        TextRenderer.DrawText(e.Graphics, "à", f, new Point(10, 10), Color.Black);
        TextRenderer.DrawText(e.Graphics, "à", f, new Point(30, 10), Color.Black);
        TextRenderer.DrawText(e.Graphics, "à", f, new Point(50, 10), Color.Black);
    }
}

或者,如果总是希望您的UserControl使用Wingdings绘制文本,您可以将该字体设置为控件的字体:

public partial class UserControl1 : UserControl {

    public UserControl1() {
        InitializeComponent();
        this.Font = new Font("Wingdings", 12);
    }

    private void UserControl1_Paint(object sender, PaintEventArgs e) {
        TextRenderer.DrawText(e.Graphics, "à", this.Font, new Point(10, 10), Color.Black);
        TextRenderer.DrawText(e.Graphics, "à", this.Font, new Point(30, 10), Color.Black);
        TextRenderer.DrawText(e.Graphics, "à", this.Font, new Point(50, 10), Color.Black);
    }
}

我认为这会稍微提高效率,因为每次控件被绘制时都不需要创建新的Font对象。

答案 1 :(得分:-1)

我已将代码更改为“优雅”格式:

namespace WindowsFormsApplication1 {
public partial class UserControl1 : UserControl {

    public UserControl1() {
        InitializeComponent();
    }

    protected override void OnPaint(PaintEventArgs e) {
        base.OnPaint(e);
        using (Font f1 = new Font("Wingdings", 12))
        using (Font f2 = new Font(Font.Name, Font.Size)) {
            TextRenderer.DrawText(e.Graphics, "à", f1, new Point(10, 10), Color.Black);
            TextRenderer.DrawText(e.Graphics, "à", Font, new Point(30, 10), Color.Black);
            TextRenderer.DrawText(e.Graphics, "à", f2, new Point(50, 10), Color.Black);
        }
    }
}
}

这使得结果绝对没有变化!
在第一次和第三次调用中,DrawText()绘制一个箭头,在第二次调用中它绘制“à”。