使用Graphics.DrawString模拟TextBox渲染 [英] Using Graphics.DrawString to Simulate TextBox rendering

查看:91
本文介绍了使用Graphics.DrawString模拟TextBox渲染的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a C# UserControl that hosts a TextBox.

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

When the custom control is disabled, I would like the TextBox to be rendered as if it were Disabled + ReadOnly (i.e. not greyed out). Therefore, when the custom control catches the EnabledChanged it sets the hosted TextBox properties accordingly.

但是,UserControl的Enabled状态优先于其他所有内容,而TextBox仍然是

However, the Enabled state of the UserControl takes precedence over everything else and the TextBox is still rendered greyed out (even though its internal ForeColor is correct).

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

Therefore, I decided to hide the hosted TextBox when the custom control is disabled and draw it myself. I can successfully render the TextBox border using the various ControlPaint.DrawXxx functions.

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

However, drawing the text results in a stretched output, when compared to the native rendering. That is, the text starts at the exact same pixel location, but character spacing is noticeably larger.

我使用TextBox自己的Font进行渲染,所以我不知道我在做什么错。我唯一可以证明的理由是C#文本框是由Windows直接呈现(使用ExtTextOut Win32 API),这会导致明显的差异。

I use the TextBox's own Font to perform the rendering so I don't know what I'm doing wrong. The only justification that I can make is that the C# TextBox is rendered directly by Windows (using the ExtTextOut Win32 API) and this results in the evident differences.

可以使用哪些选项我用来模仿本机TextBox渲染吗?

What options can I use to mimic the native TextBox rendering ?

推荐答案

区别是 Graphics.DrawString 使用 GDI + 呈现文本,而Win32 API内部使用 GDI 进行所有操作,包括在控件上绘制文本。

The difference is that Graphics.DrawString uses GDI+ to render the text, whereas the Win32 API uses GDI internally for everything, including drawing text on controls.

从.NET 2.0开始,您可以使用 TextRenderer.DrawText 方法,其中

As of .NET 2.0, you can easily mimic its appearance using the TextRenderer.DrawText method, which also uses GDI to draw.

在大多数情况下,还用 Graphics.Dra绘制图形。 wString TextRenderer.DrawText 很简单。您没有显示任何代码,因此很难举一个具体的例子。

In most cases, replacing Graphics.DrawString with TextRenderer.DrawText is straightforward. You don't show any code, so it's hard to give a specific example, though.



至于为什么必须这样做首先...禁用容器控件始终会禁用其所有子控件。在Windows中,这是一个硬规则,没有例外。当然,这是一个非常明智的选择。

如果您不希望禁用容器中的所有控件,则不应该禁用整个容器,只需禁用其中的单个控件即可。


As for why you have to do this in the first place... Disabling a container control always disables all of its child controls. That's a hard rule in Windows with no exceptions. It's a pretty sensible one, of course.
If you don't want all of the controls inside of a container to be disabled, you shouldn't disable the entire container—just disable the individual controls inside of that container.

即使采用了一种更好的呈现文本的方法,我仍然强烈建议您不要尝试重新实现 TextBox 控件。这是一项相当复杂的工作,而且仅花费几天/几周的时间您就不可能做到正确。

Even armed with a slightly better method of rendering text, I still strongly recommend that you not try and re-implement the TextBox control. It's a fairly complicated piece of work, and you're not likely to get it right with only a few days/weeks of effort.

这篇关于使用Graphics.DrawString模拟TextBox渲染的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆