UserControls - MsgEditor project
This project contains free/opensource user controls for anyone to use and/or learn from. At this moment,
1 April 2013, only 1 control is included (although you can pick a few others in my NNTPGolverd project).
The Controls:
1. A (very) extended replacement for textbox/richtextbox
I build this one with my usenet-clients message reading/composing ability in mind. In messages,
there is not only text, there are also binary objects (some of them pictures). So, in order to
show those messages, something is needed that will allow text editting as well as pictures showing.
Basically I ended up building a small word-processor that also does graphics.
Using TextBox/RichTextBox, you will find a number of limitations:
- They cannot have transparent backgrounds for some reason.
- TextBox is a very old Win32 implementation and isnt very good in multiline mode.
- richtextbox sometimes screws up the text display if you put specific characters in it.
I've seen it change my forecolor to red (for no reason) and mess up the font for any
text coming after it.
- None of them can host pictures within the control.
So initially in my NNTPGolverd project, I discarded the standard controls and I used a simple
panel with autoscrolling, then rendered the text/images into it using labels/pictureboxes. For
display only, that is fine to do, but I needed more: it also had to be capable of editing the text.
The panel wont do mouse-wheel scrolling either, unless you first of all make it 'selectable'
using a SetStyle, and ensure the panel is selected as soon as the Mouse enters it. Then, you
have to intercept specific WndProc messages and replace them with other actions in order to
make scrolling using the mouse-wheel possible. No problem at all, but the WndProc override could
make it more difficult in (future) windows-versions, and when you place a large amount of data
using labels in such a panel, rendering/filling it takes about a million years. All in all not
good enough for my usenet program. And... you cant select and copy/paste the text data in the
panel.
So I started to build - more or less - a real word-processor to host both text/images, and allow
editing in it. The most difficult part of the build is to get the measurements of individual characters
on the screen (so the cursor can be positioned at exactly the right location). I was using the
Graphics.Drawstring() stuff to do it, and tried about everything possible to get accurate readings
of the sizing, but it proved impossible (unless you revert to COM solutions, which I hate and avoid
at all costs). After the expiriments proved to be no good at all, I found out that Graphics.Drawstring
is an actually outdated call and badly maintained. So, I used TextRenderer to do both drawing and
measurements, and given you use EXACTLY the correct (and same) settings for measurement & draw,
the readings become accurate!
The end result is a single control 'EditPanel'; It has a few classes it will need, so its best to host
it in its own folder (as it is in the sample 'MsgEditor' project). When you need it in any project,
you will need to copy the folder 'EditPanel', and ensure the namespaces in all .cs files are correctly
for the target project where you wish to use them into.
Typical usages:
- As a plain (multiline) textbox: just set/get the .Text property as you would normally do on a textbox.
Do note that the panel will NOT autosize as TextBox single line does. If you need it to be
autosizing to the current font setting, it can be done (but I didnt do it) easily.
- As a full blown edit screen having both pictures & text items. You add objects to the control
as needed, and the user can mess around with them. After the user is done, you can get all the
resulting objects from the panel as you like.
Both usages can be set read-only as well.
Features:
- Depending on the item, a right click on it will show a context menu. At this
time the menu is shown, but not yet handled. That will be for later.
- It can fire generic events back to the form (which can be extended to
suit your needs).
- It can select & copy/paste text data (still working on images as well)
- Picture items show in exactly the resolution as intended; A click
on such item generates an event.
- Transparent background is no problem.
Limitations:
- Text cannot (yet) be selected by mouse movements. You will need to use shift+movement
keys for now. Ctl-C/Ctl-V will work, also with multiple lines.
- Changing the font at runtime is not yet supported. It will work though, if you
first do ClearPanel(), change font, then call AddObject() or Text to add a new item.
- There are probably a few special keystrokes I still need to build in, but the most
common ones are there now.
Methods:
BackColor
<summary>Sets the backcolor of the panel, can be set to transparent.</summary>
This, like ForeColor will allow change at runtime.
ReadOnly
<summary>Makes panel readonly (or not)</summary>
Default is read-only; if set to read/write, the current exposed text (if any) will
be selected automatically. For plain textbox usage: set this true at design time.
Text
<summary>Gets/Sets text; mimics standard textbox (multiline) behaviour.</summary>
Simple TextBox mode overload. Just get/set the text as needed.
ClearPanel
<summary>Clears the panel completely</summary>
This kills all objects in the panel; It isnt needed when you use the 'TextBox' mode.
AddObject(System.Object,System.Object,System.Object,MsgEditor.luserControls.EditPanel.EditPanel.EditPanelDescriptionAlignment)
<summary>adds a new item to the EditPanel Item can be StringBuilder, string, string[] or list(string) for text,
Image or Bitmap for picture. Description can be empty, string, string[] or List(string) Tag: empty, or
any item the caller wants. Returns objectHandle (int)</summary>
<param name="NewObject" />
<param name="Description" />
<param name="Tag" />
<returns>ObjectHandle (int) </returns>
This adds an object (text or image) to the edit panel. you can add description, an object (tag) to the item.
The object will be appended to the objects already in the panel.
ObjectCount
<summary>Get total object count.</summary>
This gives you the number of objects currently in the control, so you can
enumerate the content objects.
ObjectType(System.Int32)
<summary>Get specific object type (Image or string) of item.</summary>
<param name="ItemIndex" />
<returns>typeof(string) or (image) or null</returns>
Returns type info of the specified object.
GetObjectDescription(System.Int32)
<summary>Get description (if set) for the item</summary>
<param name="ItemIndex" />
If the object has a description set, this will return it.
GetObjectTag(System.Int32)
<summary>Get tag (if any) for the specified item.</summary>
<param name="ItemIndex" />
If you added a tag to the object when you added it, this will return it.
TextDataByIndex(System.Int32)
<summary>Get a specific item in List(string) ItemIndex below 0 means: get ALL available items.</summary>
<param name="ItemIndex" />
If you need to get a specific items' text: this is you call. It can also return ALL text items.
ImageDataByIndex(System.Int32)
<summary>Get specific image in List(Image). Returns ALL images if itemindex below 0.</summary>
<param name="ItemIndex" />
If you need a specific Image item from screen: this is your call. It can also return ALL images.
Note about images: an image object is NOT the same as a jpg,png,gif etc. It is the internal re-
presentation of whatever was put in in the first place. If you want to save it on disk, be sure
to encode it in the desired image type first.
[a few special overloads to collect all text data from the panel in one call:]
TextDataSB
<summary>Get all available text items in a stringbuilder.</summary>
TextDataString
<summary>Get all available text items in a string.</summary>
TextData
<summary>Get all available text items in a string[] array (note: no cr/lf is inserted).</summary>
This one allows you to decide whether or not to process line by line.
Events:
PanelEvent
<summary>PanelEvent fires when user clicks on picture item; will also provide the tag for the item.</summary>
The panelevent itself is generic, and can be extended for many tasks.
(and other controls will follow! Soon!)
1 Apr 2013, by GolverdCoder.