【问题标题】:Using Graphics.DrawString to Simulate TextBox rendering使用 Graphics.DrawString 模拟 TextBox 渲染
【发布时间】:2011-05-18 13:38:27
【问题描述】:

我有一个承载 TextBox 的 C# UserControl。

当自定义控件被禁用时,我希望将 TextBox 呈现为已禁用 + ReadOnly(即不灰显)。因此,当自定义控件捕获 EnabledChanged 时,它会相应地设置托管的 TextBox 属性。

但是,UserControl 的 Enabled 状态优先于其他所有状态,并且 TextBox 仍然呈现为灰色(即使其内部 ForeColor 是正确的)。

因此,我决定在禁用自定义控件时隐藏托管的 TextBox 并自己绘制它。我可以使用各种 ControlPaint.DrawXxx 函数成功渲染 TextBox 边框。

但是,与原生渲染相比,绘制文本会导致输出拉伸。也就是说,文本从完全相同的像素位置开始,但字符间距明显更大。

我使用 TextBox 自己的字体来执行渲染,所以我不知道我做错了什么。我能做的唯一理由是 C# TextBox 是由 Windows 直接呈现的(使用 ExtTextOut Win32 API),这会导致明显的差异。

我可以使用哪些选项来模拟原生 TextBox 渲染?

【问题讨论】:

    标签: .net winforms graphics controls textbox


    【解决方案1】:

    不同之处在于Graphics.DrawString 使用 GDI+ 来呈现文本,而 Win32 API 在内部使用 GDI 来处理所有内容,包括在控件上绘制文本。

    As of .NET 2.0,您可以使用TextRenderer.DrawText method 轻松模仿它的外观,它也使用 GDI 进行绘制。

    在大多数情况下,用TextRenderer.DrawText 替换Graphics.DrawString 很简单。你没有显示任何代码,所以很难给出一个具体的例子。


    至于为什么你必须首先这样做......禁用容器控件总是会禁用它的所有子控件。这是 Windows 中的硬性规则,没有例外。当然,这是一个非常明智的做法。
    如果您不想禁用容器内的所有控件,则不应禁用整个容器,只需禁用该容器内的各个控件即可。

    即使有更好的文本呈现方法,我仍然强烈建议您不要尝试重新实现TextBox 控件。这是一项相当复杂的工作,你不可能只用几天/几周的努力就能把它做好。

    【讨论】:

    • 你的建议很好。我改变了我的策略,而不是摆弄控件的启用/禁用状态,我公开了一个 ReadOnly 属性来驱动托管的 TextBox 是否为只读。
    猜你喜欢
    • 1970-01-01
    • 2014-08-13
    • 2014-07-13
    • 1970-01-01
    • 1970-01-01
    • 2014-06-22
    • 2015-03-16
    • 1970-01-01
    • 2013-03-13
    相关资源
    最近更新 更多