Archive for August, 2009

WPF: CheckBox as GroupBox Header

August 7th, 2009

This is a followup post to the one I wrote on Enabling Controls with a CheckBox. In that post we created some XAML that would enable/disable controls in the GUI based on the IsChecked property of a checkbox.

Here’s an enhancement to that:

Checkbox as header for Groupbox

So what we’re doing is giving the controls on our dialog a nice visual grouping letting the user know that they’re associated. The GroupBox element has long existed to fulfill this need. However, with this little XAML change it also doubles as a sort of access control for the items it contains.

Here’s the XAML:

<GroupBox Padding="5" HorizontalAlignment="Stretch">
    <GroupBox.Header>
        <CheckBox x:Name="chkEnableBackup">Run Backup Sets</CheckBox>
    </GroupBox.Header>
 
    <StackPanel IsEnabled="{Binding ElementName=chkEnableBackup, Path=IsChecked}">
        <StackPanel Orientation="Horizontal">
            <Label Margin="12,0,0,0">Run backup every</Label>
            <ComboBox Width="70" SelectedIndex="0">
                <ComboBoxItem>Minute</ComboBoxItem>
                <ComboBoxItem>Hour</ComboBoxItem>
                <ComboBoxItem>Day</ComboBoxItem>
            </ComboBox>
        </StackPanel>
        <StackPanel Margin="12,10,0,0">
            <Label>Path to Backup:</Label>
            <TextBox Width="200" Margin="5,0,0,0"/>
        </StackPanel>
    </StackPanel>
</GroupBox>

So all we’ve done here is add the CheckBox to the <GroupBox.Header> element of the GroupBox. Pretty slick!

This little technique is complete UI Candy and in my opinion illustrates one of the many powerful features of WPF: the ability to customize the GUI in any way you want, down to any level!

WPF: Creating a Pop Up Button Style

August 7th, 2009

So I’ve been getting pretty fancy with my GUI development, and today I wanted to design a button that would appear as just flat text until you hovered over it with the mouse, at which point it would “pop up” and look like an actual button.

Regular Button'Flat' Button

The following solution only works when run on a system with a Windows Vista/7 theme enabled, such as Aero or Basic. It will not work when run with the Windows Classic theme.

The ‘Flat’ Pop Up Button was achieved by simply setting the background and border to transparent. Here’s the XAML:

<Button Content="Click Me!" Background="Transparent" BorderBrush="Transparent"/>

The next step was to make it so that when the mouse hovers over the button it “pops up” visually and looks like your standard button. At first I tried several methods for accomplishing this using triggers to set the style of the button which were all turning out to be pretty messy since I’m not the best graphical designer.

But silly me, I didn’t realize that in this case I didn’t have to do anything special at all! I could just leave the button as it is in the XAML above and the baked in triggers for the Button would still kick in and change the appearance when the mouse hovered over it.

Here’s what that looks like:

Pop Up Button

It looks pretty cool in spots where you want a nice, Aero style button, but if the user isn’t interacting with it you don’t want all those pixels distracting from the clean whiteness that is your polished application.

WPF: Setting a Type Specific Property Value

August 7th, 2009

While XAML in WPF is probably the most powerful GUI development architecture I’ve ever used and by far my favorite, there’s still a few little tasks here and there that I just scratch my head trying to figure out.

This is probably due to my limited knowledge of XAML and how to use it properly, so until I get it all mastered I’m forced to use lines of DuctTape to get some of the results I want.

Here’s my most recent hack job. If you look at the XAML below you’ll notice that I’m making use of the Tag property of the button. This is just an example, but in real life there’s actually quite a few valuable uses for Tag.

<Button Content="Am I the right button?" Tag="False" Click="Button_Click" />
<Button Content="Am I the right button?" Tag="True" Click="Button_Click" />
<Button Content="Am I the right button?" Tag="False" Click="Button_Click" />

So in this example the user needs to click the right button. The right button is indicated by its tag property. In this case the second button is the one that works, right?

Which button is it?

Not exactly.

The code to handle this situation would look something like ths:

private void Button_Click(object sender, RoutedEventArgs e)
{
    var sourceBtn = sender as Button;
 
    bool isRight = (bool)sourceBtn.Tag;
}

Since Tag is defined as an object and I’m binding it to “False” in my XAML I thought this code would work out just fine, but it doesn’t.

The problem is Tag gets populated with a string instead of a boolean. That’s interesting, after all why shouldn’t it? How is XAML supposed to know that what I wanted to set to Tag is the boolean value False? It doesn’t.

So I had to write my XAML in such a way that it knew without a doubt that I was using a boolean value.

The first thing in accomplishing this was to include the System namespace in my XAML file, like so:

xmlns:system="clr-namespace:System;assembly=mscorlib"

Then I could declare my Tag property full out giving it a system:Boolean for its value.

<Button Content="Am I the right button?" Click="Button_Click">
	<Button.Tag>
		<system:Boolean>False</system:Boolean>
	</Button.Tag>
</Button>
<Button Content="Am I the right button?" Click="Button_Click">
	<Button.Tag>
		<system:Boolean>True</system:Boolean>
	</Button.Tag>
</Button>
<Button Content="Am I the right button?" Click="Button_Click">
	<Button.Tag>
		<system:Boolean>False</system:Boolean>
	</Button.Tag>
</Button>

And that’s it, it works! Yay!

But man, it really is ugly. Does anyone know of a cleaner, better way to accomplish the same thing? I would love to learn something new!