使用Graphics.DrawString来模拟TextBox渲染

时间:2011-05-18 13:38:28

标签: .net winforms graphics controls textbox

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

当禁用自定义控件时,我希望TextBox被渲染为好像它是Disabled + ReadOnly(即不是灰色)。因此,当自定义控件捕获EnabledChanged时,它会相应地设置托管的TextBox属性。

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

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

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

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

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

1 个答案:

答案 0 :(得分:2)

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

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

在大多数情况下,将Graphics.DrawString替换为TextRenderer.DrawText非常简单。您没有显示任何代码,因此很难给出一个具体的例子。


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

即使使用稍微更好的文字渲染方法,我仍然强烈建议您尝试重新实施TextBox控件。这是一项相当复杂的工作,只用几天/几周的努力你就不可能做到这一点。