WPF: Setting a Type Specific Property Value

August 7th, 2009 by Mel Leave a reply »

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!

Advertisement

5 comments

  1. neutron says:

    Hi,
    is there a way to pass arguments along with an event handler
    just like in html/javascript where for the onclick event will be something like: onclick=”dosomething(‘value’)”
    xaml, wpf does not allow parenthesis so i have been searching for a way to do something similar
     
    i m fairly new to .net programming so please bear with me

  2. ADTC says:

    For your original problem where you have Tag=”True” and getting sourceBtn.Tag gives you a string, just parse the string into a boolean using Boolean.Parse(…), like this:

    bool isRight = Boolean.Parse(sourceBtn.Tag);

    Of course, if you are not sure that sourceBtn.Tag will always be either True or False, you should either do the parsing in a try/catch, or use Boolean.TryParse(…) like this:

    bool isRight; Boolean.TryParse(sourceBtn.Tag, out isRight);

    That should do 🙂

    • Mel says:

      Hey ADTC,

      Thanks for the comment, all good points! In .Net any string can easily be parsed into a value of a different data type. However I believe I was trying to illustrate defining data types strictly in XAML (I was on a big XAML kick back then), although both my example and solution were overly simple and kind of useless really, as solutions such as your’s and Roland’s below are much smarter. 🙂

  3. Mel says:

    Hey Roland,

    Thanks for the feedback!

    I didn’t know anything about attached properties until you mentioned them, thus triggering some research on my part. I think they would work better!

    When I get a chance I’ll write a follow up post to this one that illustrates the superior method you described.

    Thanks,

    Mel

  4. Hi,

    You should perhaps make use of a stronlgy-type attached property.. For example, if your button is in a UserControl ‘ButtonGame”, define an attached property of this UserControl.. Once done, you could write something like “”.

    This would be cleaner than this “tag” thing.

    But the cleanest way would probably to have an associated datamodel, for example using the well-known MVVM design pattern.

    Regards,

    Roland Tomczak

Leave a Reply