WynApse Home Page
Home    Blog    About    Contact       
Latest Article:


My Tags:
My Sponsors:






Lifetime Member:

ValueConverters Intro: BoolToVisibility Converter


I'm starting a XAML series here... this could be XAML stuff or it could be Silverlight, WPF, or Windows 8... point being it's probably going to all be C# and XAML.

When I look at any major project I've done in Silverlight or WPF and look at it with an eye toward what could I teach someone from this app, one of the things thatjumps out at me is...

Value Converters

Be aware this is a beginner's article! If you've been doing XAML for a while, you already know this. About 3 or 4 articles from now though, you might want to jump in and have a read :)

So what the heck are Value Converters?

According to MSDN, "Converters can change data from one type to another, translate data based on cultural information, or modify other aspects of the presentation".

According to me, converters allow you do do some very cool things with binding that seem downright impossible if you're not familiar with them. We're going to start dead-simple to set the stage for later articles. In a nutshell, a value converter allows you to bind a variable of any sort and 'convert' it to something else that you need. The most basic converter that everyone builds is a Boolean to Visibility converter. This allows you to bind a boolean type and use it to control the visibility of an element in your XAML... and that's exactly what this first article in the series is about.

First an example

I had originally intended to do this in WPF, but decided if I did it in Silverlight, I could give you a working example right here on the page. So that's what I did.

If you don't have Silverlight onboard, go find one of your more enlightened cohorts and have them run it for you :) Beyond that, you'll have to bang the code together in some other XAML-based platform and give it a dance yourself.

In the bordered-box below is a Silverlight island on this page that contains 3 checkboxes across the top, and 3 TextBlocks going down from that. Each checkbox has control over one of the TextBlocks, which I'll explain as we go through the code.

A couple caveats:
First, I'm just doing everything in code behind because it's easier to put together a simple example for an article that way.
Second, there are more direct ways of hooking the visibility of a TextBlock up to the IsChecked parameter of a checkbox than by using ValueConverters, but the whole point of this article IS the value converters :)


Get Microsoft Silverlight


Coding it up

Getting a value converter cooking in your app takes three unique pieces of coding: 1) The converter code ... a C# class, 2) Declaring the converter as a resource in your XAML, and 3) Using the converter in your XAML. So first let's look at the larger of those three... the converter itself.

The Converter

In the box below is a value converter at it's most basic. Things to notice are that it is a public class inherited from IValueConverter. There is both a Convert and a ConvertBack method declared. I've never used the ConvertBack... possibly to be strict I should, but I've never had a problem not using one.


namespace MyNamespace
{
public class SomeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}


The value you're binding to comes in as the 'object value' parameter. By examining that value, you determine what you want to return, and it gets sent back to your XAML. Before we leave this code, here is the Convert for a basic BoolToVisibility converter:


public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
Visibility retVal = Visibility.Collapsed;
bool locVal = (bool)value;
if (locVal)
retVal = Visibility.Visible;
return retVal;
}


From that code it's easy to see that I'm defaulting the return value to Visibility.Collapsed, and if the incoming value is true, then I change the return value to Visibility.Visible. Since the value comes into the converter as an object, it has to be cast to the type it was sent as... in this case a bool.

Declaring the Converter

Normally, I'd have my converters in some 'common' module that would have to be referenced in the module in which it's used, but in this case, the converters are local to the app itself, so I simply added a namespace 'local' as shown here:


xmlns:local="clr-namespace:XAMLValueConverters01"


Next you'll need to setup a resources section in your UserControl, or add onto the one you already have like this, where I've included all the converters used in this artcle:


<UserControl.Resources>
<local:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
<local:BoolToCollapsedConverter x:Key="BoolToCollapsedConverter" />
<local:BoolToVisibilityExConverter x:Key="BoolToVisibilityExConverter" />
</UserControl.Resources>


The first part of each declaration for example "local:BoolToVisibilityConverter", is listing the source for the object, as you would with any control. You should get intellisense for this after typing "local:" once the included reference is compiled.

The second part of each declaration for example "x:Key=BoolToVisibilityConverter", is the name used when using the converter in your XAML and could be any name. I find it easier to keep the same name to avoid confusion.

Using the Converter

Now that you have all the setup done, you simply use the converter in your code as shown below:


<TextBlock Grid.Row="1"
Text="BoolToVisible"
FontSize="13"
VerticalAlignment="Center"
Visibility="{Binding TopValueChecked, Converter={StaticResource BoolToVisibilityConverter}}" />


This is code from the working example above. "TopValueChecked" is the bound "IsChecked" value for the first checkbox and will be true when the checkbox is checked. This value gets sent to the BoolToVisibilityConverter, which returns Visibility.Visible when "TopValueChecked" is true and Visibility.Collapsed when "TopValueChecked" is false.

Now that you know what the code looks like, running the example at the top of the page should be more clear, at least regarding the first checkbox and the top line of text.

A debug hint

If you didn't notice it before, if you examine the code for the converter, you'll see "object parameter" in there. We'll make use of that later in this article and even more so in following articles in this series, but for now I'll point out a debug hint I use.

If you're not sure if your converter is being called, or if you have a really complex object that you're uncertain about the logic being correct, it's nice to be able to breakpoint inside the converter. If the converter is one used lots of places, you could be hitting it a lot, so the trick would be to break only when you want. If you aren't using the parameter value, or if you have the logic in your converter set up so that you can pass in and use some 'magic' value, then you're golden for breaking.

Simply adding a parameter to the call like this:


Visibility="{Binding TopValueChecked, Converter={StaticResource BoolToVisibilityConverter}, Parameter='13'}" />


Then in the converter, add some code you can break on like this:


if ((string)parameter == "13")
{
int nIndex = 0;
}


This way you can break inside the converter and check the value you're sending. You'll find out if you really hit the converter too.

BoolToCollapsedConverter

I've also included a BoolToCollapsedConverter in this example, just for completeness. But by now you should be thinking something along the lines of "hey... if I have a parameter I can send in, why not use that?" ... and you'd be right!

BoolToVisibleExConverter

What I've got in this article called BoolToVisibleExConverter is actually the normal BoolToVisibilityConverter you'd see me using. The body of the converter looks like this:


Visibility retVal = Visibility.Visible;
bool locVal = (bool)value;
if ((string)parameter == "Invert")
locVal = !locVal;
if (locVal)
retVal = Visibility.Collapsed;
<>span class="kwrd">return retVal;


The converter is looking for the parameter to (possibly) be set to "Invert". If that's not the case, it operates exactly as the BoolToVisibilityConverter explained agove does. If, however, the ConverterParameter is "Invert", then the logic is flipped and the converter essentially becomes a BoolToCollapsedConverter.

Setting the parameter in the XAML is the same as setting the debug value above.

Also note that in the body of the BoolToVisibilityExConverter, we could easily inject the debug check for some parameter value other than "Invert", and it would have no affect on the outcome of the real use.

Now What

Now you have food for thought for the next time you need to bind something interesting in your XAML. I hope this is new and useful to some of you reading it.

Oh yeah... the project for this article can be downloaded here

In the next article we'll look at some creative ways to use some of the converter ideas. I've got a little more to talk about converters themselves and a bunch more to talk about their use. Until then...

Stay in the 'Light!
Copyright © 2006-2017, WynApse