The WPF RadioButton

Being an old VB coder, I fondly remember this control as the Option Button, but these days it’s been renamed to the RadioButton. They are used to present the user with a set of mutually exclusive options.

Adding them is simple, just use the <RadioButton> tag. For the button you wish to be the default (if any) you add the IsChecked=”true” flag.

WPF adds a huge improvement over it’s predecessor. No longer are you forced to use a container control to group your radio buttons. Instead, WPF adds a GroupName property. Take a look at this example:  

  <StackPanel>

    <RadioButton GroupName=One IsChecked=True>Option 1</RadioButton>

    <RadioButton GroupName=One IsChecked=False>Option 2</RadioButton>

    <RadioButton GroupName=Two IsChecked=False>Option 3</RadioButton>

    <RadioButton GroupName=Two IsChecked=True>Option 4</RadioButton>

  </StackPanel>

wpf045

Note the GroupName, for the first two items, I’ve set it to One, on the second two it’s Two. This means you can change Option 1 and Option 2 without affection Options 3 or 4. Go ahead and run the app, click on the options a bit and watch what happens.

In my example, I only entered two items for each, the actual number you can do is limited only by the space you have available on your Window.

The C# code for checking the value is identical to yesterday’s code for the CheckBox so I won’t reiterate it, all you have to do is look at the IsChecked property.

One last point, event though adding containers are not required to separate the option groups, it’s important to provide some sort of visual indicator so the user knows which groups do what.

The WPF CheckBox

Checkboxes in WPF are very straight forward controls, very similar to their WinForms predecessors. Adding them is a simple matter of using the <CheckBox> tag. Likely you’ll need to give each a name, so you can reference it in code.

There are also two properties that may be of use to you. First is IsChecked, this is set to true or false and as you might expect sets whether the check is in the box or not. The second is IsEnabled, and determines whether users may use the control. You can combine these in any combination, as you can see in the example below.  

    <StackPanel>

      <CheckBox Name=cbxOne IsChecked=False>Check Box One</CheckBox>

      <CheckBox Name=cbxTwo IsChecked=True>Check Box Two</CheckBox>

      <CheckBox Name=cbxThree IsChecked=False IsEnabled=False>Check Box Three</CheckBox>

      <CheckBox Name=cbxFour IsChecked=True IsEnabled=False>Check Box Four</CheckBox>

      <Button Name=btnShowMe Click=btnShowMe_Click>Show Me</Button>

    </StackPanel>

This little bit of code produces this attractive dialog:

wpf044

Note I’ve added a button, the purpose of the button is to show you a dialog that determines whether a box is checked.  

    void btnShowMe_Click(object sender, RoutedEventArgs e)

    {

      StringBuilder sb = new StringBuilder();

 

      if (cbxOne.IsChecked==true)

        sb.AppendLine(“Box One is Checked”);

      else

        sb.AppendLine(“Box One is Unchecked”);

 

      if ((bool)cbxTwo.IsChecked)

        sb.AppendLine(“Box Two is Checked”);

      else

        sb.AppendLine(“Box Two is Unchecked”);

 

      MessageBox.Show(sb.ToString(), “CheckBox”);

 

    }

Here you can see all that’s needed is to check (no pun intended) the IsChecked property. You may wonder why I had to use the bool case in the cbxTwo example. It turns out the IsChecked is actually of type bool? and not bool. A bool? is a bool that can hold a null value in addition to true/false.

In the cbxOne area, the .Net Framework can handle converting the bool? to a bool before it does the equal. In the second example, .Net needs that conversion to be made explicit.

Go ahead and run the app, check the boxes and click the Show Me to see the messages. I didn’t bother to repeat the same code for boxes three and four, since they are disabled, but they’d work the same way.

The WPF CheckBox is something you should check out! (OK, that time the pun was intended! ;-)

The WPF ComboBox

The other major listing control to cover is the ComboBox. It turns out that they are almost identical to ListBoxes. This simple code will add a combo box to your container (I’m using a StackPanel) and put two items into it.

      <ComboBox>

        <ComboBoxItem>Item 1</ComboBoxItem>

        <ComboBoxItem>Item 2</ComboBoxItem>

      </ComboBox>

Running will produce the predictable window with a drop down combo box and two items. If you want the user to be able to edit or enter his own text, you will need to set the IsEditable property to true and IsReadOnly to false in the <ComboBox> header.

Also like the ListBox, the ComboBox can contain complex items.

      <ComboBox>

        <ComboBoxItem>

          <StackPanel Orientation=Horizontal>

            <TextBlock Width=100>Anna</TextBlock>

            <Image Source=D:\Presentations\100Anna.jpg Height=100 />

          </StackPanel>

        </ComboBoxItem>

        <ComboBoxItem>

          <StackPanel Orientation=Horizontal>

            <TextBlock Width=100>Raven</TextBlock>

            <Image Source=D:\Presentations\100Rave.jpg Height=100 />

          </StackPanel>

        </ComboBoxItem>

        <ComboBoxItem>

          <StackPanel Orientation=Horizontal>

            <TextBlock Width=100>Ammie</TextBlock>

            <Image Source=D:\Presentations\100Ammie.jpg Height=100 />

          </StackPanel>

        </ComboBoxItem>

        <ComboBoxItem>

          <StackPanel Orientation=Horizontal>

            <TextBlock Width=100>Kids</TextBlock>

            <Image Source=D:\Presentations\100Kids.jpg Height=100 />

          </StackPanel>

        </ComboBoxItem>

 

      </ComboBox>

wpf040

Note from the image above, if the contents of the drop down are too big it wil drop below the bottom of your current Window. Additionally, if you use automatic sizing the combo box will adjust itself rather oddly depending on the contents. For that reason, you may wish to set a default width rather than letting the combo box do it for you.

So how do we get data back out of the ComboBox? Well, if all we have is text, we can do just like we did with the ListBox, convert the selected item to a combo box item and get it’s Content.ToString property. But what if it’s like the above example, a mixture of text and images? Well we have to dig just a little, but it’s not that difficult if you understand the tree WPF creates.

  <StackPanel>

    <ComboBox Name=myComboBox  >

      Item Data Omitted for Brevity

    </ComboBox>

    <Button Name=myButton Content=OK Click=myButton_Click />

  </StackPanel>

Note I made two changes. First I added a name to the ComboBox, that way I can address it in code. Next I added a simple button control, we’ll use it to show what is currently selected. Just for the fun of it, I used the Content tag instead of placing it between the <Button></Button> tags, you may run across that form of syntax at some point and should be aware of it.

Now we need to add a little code to the myButton_Click event.

    public void myButton_Click(object sender, RoutedEventArgs e)

    {

      ComboBoxItem cbi = myComboBox.SelectedItem as ComboBoxItem;

      if (cbi != null)

      {

        StackPanel sp = cbi.Content as StackPanel;

        TextBlock block = sp.Children[0] as TextBlock;

        MessageBox.Show(“You picked “ + block.Text);

      }

      else

      {

        MessageBox.Show(“You haven’t picked anything yet”);

      }

    }

First, I got the current ComboBox item, and stored it in the cbi variable. I then check to see if it’s null, which it will be if the user hasn’t selected anything. If it is, we can show them the traditional “hey dummy” message, as I did in the else clause.

If you recall, the contents of the ComboBoxItem are a StackPanel control, so next I get a reference to it in the sp variable.

Next, I suppose I could iterate of the Children of the StackPanel, but since I know that the TextBlock I want is the first child, I’ll simply reference it directly as element zero and return it to the block variable.

Finally we can get to the actual text for the row the user picked. We can simply reference the TextBlock’s text property in the message box. When the app is run, you should see these results:

wpf041

The same techniques I use here would also be applicable to the ListBox we’ve seen previously, simply replace ComboBoxItem with ListBoxItem.

The WPF ComboBox can be quite useful for providing a compact way for users to select complex items.

Downloading a Virtual PC Image of Visual Studio 2008 Beta 2

During last week’s WPF class, several of my coworkers expressed an interest in using the 2008 edition to experiment with WPF. They were concerned installing the beta on their production box could damage their boxes, even though in theory part of the beauty of .Net is the ability to run multiple versions of the framework side by side.

To alleviate those fears, Microsoft has provided a Beta of 2008 already in a ready to run Virtual PC. First, you’ll need to have Microsoft Virtual PC 2007 installed on your box. If you don’t, you can grab a copy from

http://www.microsoft.com/downloads/details.aspx?familyid=04D26402-3199-48A3-AFA2-2DC0B40A73B6&displaylang=en

(Even though the instructions indicate it should work with VPC 2004 SP1 or Virtual Server, I haven’t tried it with them. Virtual Server should be fine, but I would highly suggest upgrading your VPC 2004 to 2007 if you haven’t done so already, there’s lots of nice new features that make it worth the effort.)

Now you can grab the 2008 image. You will actually need two sets of files, the base image and the 2008 Beta 2 image. You can download the 2008 Beta 2 from

http://www.microsoft.com/downloads/details.aspx?FamilyID=3b72271c-e996-4989-898d-72d684966ce6&DisplayLang=en

The download is in the form of 7 files, the first is an exe and the rest are rar files. Download all 7 to a folder and run the exe, and it will combine all 7 to create the virtual pc image.

Make sure to read all of the instructions on this page! The user ID and password to login to the virtual image, along with a link to the needed base image, are contained in the instructions!

Now you need the Orcas base image. If you read through the instructions you saw the link to the compressed file, right above the user id / password. Right click on the link and “Save As…” to the same folder where you saved the other items. Run it to uncompress the base image.

OK, in a folder you should now have OrcasBeta2_VSTS.vmc, OrcasBeta2_VSTS.vhd, Base01.vmc, and Base02.vhd. I also copied the user id and password from the above linked page and saved it in a text file called “Orcas Beta 2 user id and password.txt”, just so I could remember it easily.

When you login, it tells you that the password expries today, and asks if you wish to change it. I’ve always just said no, and it seems to work fine, but you are welcome to change it if you want.

When you shut down the Virtual PC, you will be prompted first for why you are shuting down. This is a Windows Server 2003 prompt, I just select “Other (Planned) under the option and put an ‘x’ for the comment. Once you do the OK button will be enabled.

Next, Virtual PC prompts you, to see if you want to commit your changes or abandon them. If you select “Commit changes to the virtual hard disk”, any changes you made will be saved and ready for next time. If you choose “Delete undo disk changes”, everything you did during that session will be lost forever.

Since it’s just a virtual image, I usually pick commit, but if you have really hosed things up you might want to know about the Delete option.

All of the software I’ve mentioned here is free, so there’s no reason why you can’t run this at home, even if you don’t have an MSDN subscription. Be warned, although Microsoft hasn’t specified a date I would think the image will expire not long after the release of the full Visual Studio 2008 product.

Using the virtual image will allow you to experiment with WPF, as well as the new 2008 features in a safe, risk free environment.

Note: If you want to use Visual Studio 2005 to write WPF (as well as other .Net 3.0 projects), I have documented the bits you need to download in this post:

http://arcanecode.wordpress.com/2007/08/20/installing-the-wpf-bits/

More WPF Resources

Walt Ritscher of Wintellect was in our offices this week, teaching us WPF. Great guy, really knows his stuff, and has a blog well worth checking out at

http://wpfwonderland.wordpress.com/

There’s a great training site on XAML/Silverlight called Nibbles. Be warned the site is done in Silverlight, so for now you’ll need to use IE and have Silverlight installed.

http://www.nibblestutorials.net/

Fellow southern blogger Keith Rome has a blog on WPF and Silverlight:

http://www.mindfusioncorp.com/weblog/

Tim Sneath has a lot of good info on Silverlight:

http://blogs.msdn.com/tims/default.aspx

Finally, this isn’t specifically a WPF resource, but our regional developer evangelist and all around swell guy Doug Turnure has a posting of .Net bloggers in Georgia, Alabama, and Mississippi:

http://blogs.msdn.com/dougturn/archive/2007/08/19/most-popular-bloggers-in-georgia-alabama-and-mississippi.aspx

Update: September 15, 2007 – I wanted to add one more resource. I picked up Pro WPF by Matthew MacDonald (http://www.amazon.com/Pro-WPF-Windows-Presentation-Foundation/dp/1590597826/ref=pd_bbs_3/104-6226587-5048708?ie=UTF8&s=books&qid=1189884771&sr=8-3 or http://tinyurl.com/2pw8z9) I have several of Matthew’s books and have always enjoyed his writing, and this book appears to be another winner. It’s a good companion to the Adam Nathan book, as each book goes into some areas the other doesn’t.

Pro WPF

TouchCursor 1.3 Released

If you’re not familiar with TouchCursor, it’s a great utility for turning the “home” keys (keys like i, j, k, l, etc) into up arrow, left, down, right, etc. For my initial review, see my post at http://arcanecode.wordpress.com/2007/05/11/arcane-software-touchcursor-for-us-keyboard-geeks/

Now, I have an incredible story of customer service to share. Late last Saturday night I was on the forums on Scott Hanselman’s site ( http://www.hanselman.com/forum/ ) and was having a ‘conversation’ with someone in the Productivity Tools area on TouchCursor. I wondered aloud how hard it would be to change the activiation key from the spacebar to something user assignable. So I shoot off an e-mail to the support site and head off to bed.

When I wake up Sunday, I have an e-mail from the author saying he didn’t think it would be all that hard, it’d be more work getting all the help updated. I thanked him and since I’d made the suggested offered to do any beta testing. And off I went thinking it’d be a while.

I get home from work Monday, to find an e-mail with a link to the Beta version of TouchCursor! Gleefully I download and test away, finding no issues and trying a variety of activation keys.

And what a list! Check this out, and this is just a sample:

touchcursor_activation_options

For now I’m trying caps lock as my activation key because I seldom use it, and it’s close to my pinky just between shift and tab. Seems the most natural so far. But to get back to my story…

I reported my results back, and on Wednesday morning got the e-mail the new version had been released! Talk about swift response.

Take a look for yourself, download the current version at http://touchcursor.com/ . It’s shareware, so you can try it before you buy, and buying is pretty painless, a mere twenty dollars (US). There’s even a “no install” version, in case you want to run it as a portable app from your USB drive.

TouchCursor has made it to the short list of must have tools in my arsenal. After service packs, virus protection and firewalls it’s one of the first things that gets installed. I challenge you to try it for 30 days and see if you don’t get hooked!

Standard Disclaimer: I have no financial association with Rare Pebble Software, other than having purchased the TouchCursor software. Just a very satisfied customer.

Scrolling in WPF

I realized in my last post on WPF ListBoxes I overlooked a basic concept, how to make the ListBox scroll when there’s more items than can fit. Let’s return to the code from Monday, but resize the Window so only the top two pictures show. Running the app doesn’t change anything, the top two still show with no way to scroll down.

It turns out this is quite easy to fix, in several ways. First, many controls such as the containers (WrapPanel, for example) or listing controls (ListBox, TreeView to name two) have built in ScrollBars. The reason they did not appear in our example is because the ListBox was inside a StackPanel, and the StackPanel extended below the window edge. As such the ListBox didn’t realize it wasn’t fully displayed.

The simple way to fix then, is to remove the StackPanel and have the ListBox be the only thing on the window. As soon as we do, Vertical Scrollbars automatically appear.

wpf037

Next, if we wanted to, we could wrap the entire panel in <ScrollViewer> tags. ScrollViewer is a XAML tag that will take whatever is inside and move with scrollbars, as needed. What you need to understand though is you’re moving the entire StackPanel, not just the ListBox.

To demonstrate, let’s add a text block to stack panel, just above the list box.  

  <ScrollViewer>

    <StackPanel>

      <TextBlock Background=LightBlue>Pick A Row</TextBlock>

      <ListBox Name=lbxCool>

      <!– ListBoxItems omitted for brevity –>

      </ListBox>

    </StackPanel>

  </ScrollViewer>

Now if you run the program, you’ll see the text block scrolls up with the list box.

wpf038

Note the text block has indeed scrolled up off the screen.

The best way to solve this would be to move the contents to a Grid. The grid sizes correctly take up the space, and allows the list box to automatically display it’s scrollbars.  

  <Grid Name=myGrid >

    <Grid.RowDefinitions>

      <RowDefinition Height=20></RowDefinition>

      <RowDefinition></RowDefinition>

    </Grid.RowDefinitions>

    <TextBlock Grid.Row=0 Background=LightBlue>Pick A Row</TextBlock>

    <ListBox Name=lbxCool Grid.Row=1>

      <!– ListBoxItems omitted for brevity –>

    </ListBox>

  </Grid>

wpf039

If you need horizontal scrollbars, you can add the  ScrollViewer.HorizontalScrollBarVisibility=Visible” tag to the ListBox declaration.

And there you go, a few ways you can add scrolling to your ListBox, or to an entire container using the <ScrollViewer>.

Follow

Get every new post delivered to your Inbox.

Join 103 other followers