Creating and consuming value converters

A value converter allows you to dynamically convert values during the process of data binding before the bound value is actually used. A value converter at heart, is a custom class that inherits from the IValueConverter interface. This interface contains two methods—Convert and ConvertBack—which we have to implement. Once the value converter is created, we can use it directly in our XAML.

Converters let us define custom logic for the different properties we have in our application. It is not uncommon to see a converter that converts one type of value to a completely different type, for example, a converter that converts a number value to a color value. Another example would be a conversation of text to Boolean values so a checkbox can be checked based on certain words.

Let's go ahead and create our first converter and see with firsthand experience why this feature is so powerful.

Creating your first converter

Open the Chapter5-Converters project from the downloadable content of this book in Visual Studio 2010. Build and run the application and you should get the result, as shown in the following screenshot:

Creating your first converter

This application allows you to change the color of the rectangle by using the Choose your color drop-down menu above it. The thing is that if you try to change the color using that drop-down menu now, nothing happens. If you think about it for a minute, you'll realize we now have two completely different types of values, which we are going to work with in order to change the color of the rectangle's fill—the combobox color names (strings) and the actual color for the rectangle fill (SolidColorBrush). This is where value converters come into play. We are going to use a string value on the Fill attribute of the rectangle, and by using a value converter, we'll convert it into something the Fill attribute can understand—SolidColorBrush.

Under the Classes folder in the project, create a new class called ColorConverter.cs.

Change the class declaration so that it will inherit from the IValueConverter interface and implement the interface. Your class should look as follows:

public class ColorConverter: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)
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}

The interface requires us to implement two methods—Convert and ConvertBack. The Convert method is used when the data is moving from the source to the target; in our example that would be when the Fill property of the rectangle receives its string binding. ConvertBack is the exact opposite; it is used when the data moves from the target back to the source. We won't be using the ConvertBack method in our example, so you can leave it as not implemented. Now it's time to implement the Convert method. We know we are getting a string as input, and based on that string, we will output a SolidColorBrush object. Replace the content of the Convert method with the following code snippet:

string ChosenColor = value!=null ? (value as ComboBoxItem).Content.ToString() : null;
switch (ChosenColor)
{
case "Red":
return new SolidColorBrush(Colors.Red);
case "Blue":
return new SolidColorBrush(Colors.Blue);
case "Black":
return new SolidColorBrush(Colors.Black);
}
return null;

Here, there's nothing that we haven't seen before. We first check if the value that we receive from the binding expression is not null. If it isn't, we are casting the value as ComboBoxItem, because this is the item that we receive from the binding (check the ColorEntity class, and you'll see that the TheColor property is defined as ComboBoxItem type), and then use the ToString method on its content to get the name of the color the user chose from the drop-down menu.

Once we have the color name, we will use a simple switch/case statement to return the correct SolidColorBrush based on the chosen color.

Our converter is now complete, so it's time to use it in our binding expression by using the Converter object of the Binding class. In order to be able to use our new converter in XAML, we first have to add it as a resource. We will discuss resources in detail in Chapter 7, Structuring Applications, but for now it's enough to know that a resource is a piece of code or style that you can reference in your XAML. Resources, like styling, which we discussed earlier, can be defined on various levels from element to page. In this case, we are going to add the element to the page level, so open the App.xaml file and add the namespace for the Classes folder of our project as local:

xmlns:local="clr-namespace:Chapter5_Converters.Classes"

Next, we need to add the converter itself as a resource. Resources are accessed in XAML by their Key property, so make sure you use that property when setting your resource. Add the following line of code between the opening and closing of the Application.Resources elements:

<local:ColorConverter x:Key="ColorConverter"/>

That's it. We can now access our converter in XAML by using its Key value—ColorConverter.

Open the MainPage.xaml file and change the rectangle's Fill property as follows:

Fill="{Binding TheColor,Converter={StaticResource ColorConverter}}"

The syntax here is as follows; we first tell the Fill property that it is bound to the TheColor property. We then use the Converter object and bind it to the ColorConverter resource we defined earlier using the StaticResource keyword. Can you tell the reason why the fill will change every time the drop-down value changes? (Hint: it's got to do with an interface).

Build and run your application, and you will see that every time you change the value of the combobox, the rectangle's fill changes accordingly:

Creating your first converter

Passing parameters to the value converter

There may be times when you wish to pass parameters to your value converter. Passing parameters is easily done by using the ConverterParameter object exposed by the Binding class. Let's assume we want to pass the value of'true' to the converter in the previous example. All we have to do is change the Fill property's binding expression as follows:

Fill="{Binding TheColor,Converter={StaticResource ColorConverter},ConverterParameter='true'}"

As parameter is an object you can practically pass on to it just about anything you want. This can be useful if you need to pass more than just a single parameter to your converter. Once set, you can read this parameter back in your converter class using the parameter argument.

While binding is most commonly done in the XAML layer, sometimes you may need to create dynamic binding in code behind. The following code snippet is a representation of the preceding binding expression in the code behind layer of the application:

Binding binding = new Binding("TheColor");
binding.Source = entity;
binding.Converter = new ColorConverter();
binding.ConverterParameter = true;
rect.SetBinding(Rectangle.FillProperty, binding);

We first initiate a new instance of the Binding class and pass it the name of the property we are binding to. Next, we set the source of the binding, the converter if needed, a converter parameter. Finally, we use the SetBinding method on FrameworkElement we wish to use (in our case, rect is the rectangle we used so far), and specify the name of the property we wish to bind and the binding instance.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.149.27.72