Suppose I am displaying a bitmap and want to allow text to be placed on that bitmap. I can display a RichEdit or TextBox control at the location and allow the text to be typed in at a certain font/size etc... but then the user can "see" the rectangular text entry control appear and disappear upon entry/edit and the edit cancel. It also covers the bitmap while entering/editing the text. My question is, how is this done such that the text entry control window is "transparent" or not "visible".
Again, if there is text on the bitmap, the user clicks on the text and viola the caret appears in the text, without displaying a visible rectan开发者_如何学Gogular control like textbox, richedit etc..., the text just "magically" becomes editable.
Is there a way to do this "transparent background" text entry in .NET?
A few options come to mind:
It may not be a bad thing to show a text entry box. This makes it clear to the user that having clicked on the bitmap they have entered a new "mode" and are now able to enter text. This is consistent with editing item names in a treeview, or editing a filename in a Windows file explorer, for example.
TextBox supports BorderStyle.None, but doesn't allow a transparent background (presumably because it would have to preserve the background during editing operations). It's easy to give this a try to see if it works well enough for your needs.
It would be very easy to write precisely the behaviour you want into your display - i.e. dispense with 3rd party controls entirely. You just have to render the text, and during editing add in the caret display (i.e. draw a simple line at the insertion position), and handle keypresses to add or remove text at the caret position. You just have to separate the rendering of the text and the background so that you can re-render it as the text is changed.
The easy way to do this is to use WPF's TextBox control. You can easily set the background to be transparent:
<TextBox Text="{Binding MyProperty}" Background="Transparent" />
To make the entire textbox transparent except for its content, just use a ControlTemplate:
<TextBox Text="{Binding MyProperty}">
<TextBox.Template>
<ControlTemplate>
<ScrollViewer Name="PART_ContentHost" />
</ControlTemplate>
</TextBox.Template>
</TextBox>
If you are still using WinForms it is much more difficult. You have three options:
It sounds like the type of application you are doing is already a great candidate to WPF so I would definitely switch to WPF if you aren't too far into it. Besides transparent textboxes, WPF has many other advantages over WinForms that can dramatically increase your developer productivity, such as advanced data binding and templating.
If you're stuck with WinForms but can render the area behind the TextBox in WPF, use a WPF ElementHost to display that whole section of the UI using WPF and leave the rest of your code as WinForms.
Otherwise writing your own TextBox replacement control is probably the best you can do.
One way would be to create a new user control by inheriting from TextBox
and then overriding the OnPaint
method? I would use .NET Reflector to see what's going on in the original method and try to figure out how to render the text without the background/frame.
精彩评论