Using the “Tag” Field And Triggers To Avoid Writing a Value Converter in WPF
I was working on a project recently and I wanted one of my layout controls to have a different margin based on a certain piece of data.
(It’s a long story… let’s just say that this is a good post if you want to change properties of a control based on a piece of data of a different type.)
So… for the sake of the argument, let’s say that I want my control to have a margin of “4,4,4,4” if my data returns “dog” and I want it to have a margin of “2,2,2,2” if my data returns “cat” and a margin of “0,0,0,0” if the data is anything else.
Normally, I would use a value converter for this. My problem was that I was sick of using value converters for things so specific and using them only a couple times in my application. So I decided I wanted to do this one with styles and triggers.
First thing I did was bind my data to the “Tag” field.
<Border Style=”{DynamicResource MyBorderWithTriggers}” Tag=”{Binding MySpecialData}” >
Then, I created a style for my Border layout control. If you’re in Blend, go to Object –> Edit Style –> Create Empty…
Create a new property trigger by clicking on the “+ Property” button and change the property to “Tag”.
I couldn’t find a way to type “dog” into the field value, so I did it in the XAML (full XAML sample below, for those of you who want to cut to the chase… you know who you are).
With the property trigger highlighted, you’ll see a “Trigger recording is on” sign in the corner of your canvas.
Just change all the properties you want. Of course, in this case, I’m just going to change the Margin property. If we do the same thing for the “Cat” contingency, we get the following style.
<Style x:Key=”MyBorderWithTriggers” TargetType=”{x:Type Border}”>
<Setter Property=”Margin” Value=”0,0,0,0″/> <Style.Triggers>
<Trigger Property=”Tag” Value=”Dog”>
<Setter Property=”Margin” Value=”4,4,4,4″/>
</Trigger>
<Trigger Property=”Tag” Value=”Cat”>
<Setter Property=”Margin” Value=”2,2,2,2″/>
</Trigger>
</Style.Triggers>
</Style>
And we end up with a layout that changes its properties based on a bound value. And we don’t have to write endless value converters. Pretty handy… or at least I thought so.
0 Responses to Using the “Tag” Field And Triggers To Avoid Writing a Value Converter in WPF
Awesome idea, thanks for the tip, I will probably (ab)use it to death!
Richard
This is very interesting. It got me thinking. Could you use this technique to combine multiple styles into one neat style. For example, I have a handful of border styles for different areas in a project. At the moment I’m writing styles for each border. I use “BasedOn” to link all these to a “BorderBase” style, so things like margin and padding are consistent. I really like the idea of using tag to trigger these different versions from one new combined style. Are there any downfalls to this idea? Are there better ways to refine things a bit? Anyway… really enjoyed the post. Thanks much.
Great article! Tnx for sharing! I also found a really interesting article with source code examples on using WPF in visualization cartographical objects. Here is a link http://techzone.enterra-inc.com/architecture/cartographical-objects-visualization-using-wpf/