Archive for the ‘Winforms’ Category

Winforms: Multiline Label; Display QueryString In Label Control

June 8, 2011

I was asked to produce a tiny Winforms app which would generate an encoded checksum for a QueryString that is consumed by one of our Web Applications. Because the encoding is based on an MD5 Hash of various data elements this Winforms app will enable our Testers and partner organisations to generate that checksum automagically.

When it came to displaying the generated checksum I encountered a problem or two:

  • When using a TEXTBOX, the QueryString would always break on the leading “?” leading to an ugly output, the first line being a “?” by itself
  • Labels are single line creatures meaning the QueryString was truncated i.e. only displayed up to the length of the Label control: there is no line wrapping
  • The ampersands in the query string were not output to the screen when using a Label control

Multiline Label
To achieve a Multiline Label: Set the Maximum Width property of the label to the same value as the Width property; Set the Height property of the label to a value that will enable it to show multiple lines; set the AutoSize property of the label to True. Thanks to Riff on the MSDN Visual Basic Forum.

Displaying Ampersand In Label Control
The reason that a Winforms Label control cannot display Anpersand is that “&” is interpereted as part the Mnemonic shortcut to the Text Field associated with the Label. To get around it, replace “&” wih “&&” in the string before displaying it or set useMnemonic to False. More details here c/o Cody Gray on Stack Overflow

Instigating the above fixes for my Label caused the Query String to display the full QueryString ampersands without breaking on the leading “?”. BUT, the value CANNOT be cut ‘n’ pasted from the Label control for use in a browser, which made it about as useful as a plywood firetruck at a refinery explosion.

So I went back to using a readonly TEXTBOX. However, semi-good news, the break-on-leading-question-mark-problem only occurs on strings shorter than the label width. So, I gave the users an option to prepend a base URL to the QueryString which covers the obscenity for long QueryStrings as the “?” is no longer the leading character.

Advertisements

Winforms MultiLine TextBox Background Colour Is Dark Grey On Vista Only

March 8, 2010

Scenario

I am maintaining a Winforms app. My DEV machine is running XP, but my user is running Vista. Within a GroupBox I added a multiline TextBox and styled it to look like a Label by setting BackgroundColor of the Textbox to System.Control in the Visual Studio Properties of the Textbox and making the TextBox borderless. The Textbox rendered nicely in XP but on Vista the Background colour was rendered as Dark Grey instead of the colour System.Control.

To try and force Vista to render the TextBox background as the colour System.Control, I found out what the RGB Values are for the colour System.Control and set the TextBox Background to that value in the Page Load event. This did not work.

After some Googling I located a couple of posts on the issue which indicated that there is some bug relating to rendering of Multiline Textboxes in Winforms:

Black Background Appearing In ReadOnly TextBox For An Application In Vista Machine

Multiline Textbox With Vertical ScrollBar In A SplitContainer On A TabControl In Vista

This self-explanatory post from Code Project, How To Make A TextBox/RichTextBox Transparent was reported by some correspondents to help them work around the Vista rendering issue.

Demetres Zarkadoulas in this Windows Developer Centre Forum post crystallized the issue: Problem With TextBoxes And Transparent Group Boxes In Vista

This seems to be a problem of the textbox in any transparent container in Vista.

Armed with hints from the links above I added a few different multiline TextBoxes with varying Properties to my Form to see which styles would render the Background Colour correctly under Vista. I found there were a several ways to solve the problem:

  1. Move the Multiline TextBox out of the GroupBox
  2. Give the TextBox a border (BorderStyle 3DBorder will do it)
  3. Use TransparentRichTextBox (add it to your GroupBox dynamically in Code-Behind)
  4. Put the TextBox on top of a Panel (This is what I ended up doing.)

So, if you’ve got a MultiLine TextBox inside a GroupBox on Vista and the Background Colour renders Dark Grey or doesn’t render to the shade you want, do any of the above.

DataBinding WinForms CheckedListBox

October 12, 2009

Noting some confusion in the Greater Google on the subject of the CheckedListBox, I want to make it clear that this article is about the WINFORMS CheckedListBox class (System.Windows.Forms.CheckedListBox), NOT the WebForms CheckBoxList class (System.Web.UI.WebControls.CheckBoxList). So back to your Postbacks all you WebForms freaks.

Generating CheckedListBox Text
The CheckedListBox is a ListBox which includes a CheckBox to the left of the display text. The display text is computed using the ToString method of the object in the Items collection of the CheckedListBox.

It is also possible, however, to generate the text in each CheckedListBox entry by associating the CheckedListBox with a DataSource and setting the DisplayMember field of the CheckedListBox.

Microsoft do not encourage the use of CheckedListBox DataSource. None of the DataSource, DisplayMember or ValueMember members of CheckedListBox appear in the Intellisense for the control or in the Designer Properties Window because Microsoft has added the Browsable=false attribute to these properties. In the MSDN example, programmers are referred directly to the Items collection as the means of wiring up the control:

To add objects to the list at run time, assign an array of object references with the AddRange method. The list then displays the default string value for each object. You can add individual items to the list with the Add method.

Microsoft MSDN advises users not to use the DataSource member of CheckedListBox because this control is not intended to be DataBound and unpredictable results can ensue if you use the control in a DataBound way. However the DataSource, ValueMember and DisplayMember members can be used as I discovered from Moz2 in this MSDN social forum thread

Why Would You Bother ?
It’s a fair question. For me, I needed to produce a Windows Form with identical look and feel to an existing form which utilised a CheckedListBox, but for processing efficiency also required a SelectedValue member. That led me into a fruitful Googling session which I am now sharing with you.

Setting CheckedListBox DataSource
You can set the DataSource to any Collection. But you must set DataSource after DisplayMember is set. Here’s some VB.NET for your reading pleasure:


'Event Handler for WebSiteType dropdown selected index changed
'Update Listed Domains in CheckBox List clbWebDomain based on selected WebSiteType
Private Sub cboWebSiteType_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles cboWebSiteType.SelectedIndexChanged
Me.clbWebDomain.DataSource = Nothing
Me.clbWebDomain.Items.Clear()
...Update Me.WebDomainMappingList...
Me.clbWebDomain.ValueMember = "DomainCode"
Me.clbWebDomain.DisplayMember = "URL"
Me.clbWebDomain.DataSource = Me.WebDomainMappingList
...Code to initialise clbWebDomain.Items.....
End Sub

WebDomainMappingList is a GenericList of my Custom Class WebDomainMapping.

Since that WebDomainMapping Class is only used for temporary processing, I actually implemented it as a Structure. I didn’t put in a ToString implementation as I wanted it clear via the DisplayMember that I wanted to display the URL property…and that leads me to my next point, the DisplayMember and ValueMember members must refer to Properties of the Objects/Structures in the Items collection of your CheckedListBox. They cannot be mere fields otherwise your CheckedListBox will fill up with garbage.

Therefore, the following will NOT work:

Friend Structure WebDomainMapping
Dim URL As String
Dim DomainCode As Integer
End Structure

Putting an Object/Structure like this into the Items collection of a CheckedListBox and then using the URL property as a DisplayMember will cause the following output to your CheckedListBox for all the entries. This is actually the default ToString() representation of the object in your CheckedListBox Items Collection

Namespace.frmReport+WebDomainMapping
Namespace.frmReport+WebDomainMapping
etc.

An Object/Structure definition like this will work. It wlll allow URL to be used as the DisplayMember of the CheckedListBox.

Friend Structure WebDomainMapping
Private _URL As String
Public Property URL() As String
Get
Return _URL
End Get
Set (ByVal value As String)
_URL = value
End Set
End Property

Private _DomainCode As Integer
...Property Declaration for DomainCode....
End Structure

Directly Initialise The Items Collection Too
It is not enough merely to initialise the DataSource member of CheckedListBox. You must also directly initialise the Items Collection if you don’t do this you will not get anything at all displayed in the CheckedListBox.

Naturally, the Items collection must contain EXACTLY the same Objects as the DataSource.

Remember, true DataBinding as represented by DataSource, DisplayMember and ValueMember is not officially supported for this control, so utilising these members may not provide the functionality you would expect or may not work at all. For example, here the Items Collection is not automatically populated by assigning the DataSource. What you can do, as I have done, is patch together an implementation or approximation of DataBinding for CheckedListBox. The functionality, or at least most of it, is there because it is inherited from Base Controls.

Final Caveats
The partial implementation of DataBinding in CheckedListBox and hence its flaky functionality is recognised by Microsoft as a bug (see preceeding links), but there is no guarantee this will be fixed to support full DataBinding. Microsoft may decide to chop DataSource from CheckedListBox entirely. I used the above workaround in version 2.0 of the Framework. Who knows, it might be gone or not work at all in later versions.

Why DataBinding Can Only Be To Properties and not Fields
Nikhail Koltari who is a Software Architect at Microsoft, explains some of the reasons why here.