Thursday, March 30, 2017

In Tip #6, we took a vector image resource and set it to Freeze = True in the XAML markup. Suppose that you need the resource to freeze at some point later in the application's execution. You can simply add this code to that point in the application:

If mySimpleImage.CanFreeze Then ' Makes the vector image frozen. mySimpleImage.Freeze()End If

Yes, I'm giving VB some love in today's tip.

Checking CanFreeze is necessary because not all Freezable objects can be frozen at every point in a WPF application's lifecycle. If Freeze() is called on an object that cannot currently be frozen, an exception will be thrown.

Monday, March 27, 2017

The next several tips will examine Freezable objects. The description from MSDN:

A Freezable is a special type of object that has two states: unfrozen and frozen. When unfrozen, a Freezable appears to behave like any other object. When frozen, a Freezable can no longer be modified.

A few examples of WPF Freezable objects are Brushes, DrawingImages and Animation KeyFrames. If an application uses any of these resources and they are not going to be modified, they should be frozen. This will improve the performance of the application, as less processing will be used to re-render graphical elements.

Here is a quick example of Freezing a DrawingImage. Consider vector graphics used in fixed-size elements on a window (toolbar buttons, for example). These are good candidates to be frozen.

Like the IValueConverter, the class must implement Convert and ConvertBack methods. The difference being the multiple values come in as an object[] parameter in Convert() and go back out as an object[] return value in ConvertBack(). The following example takes two string values as input and returns them concatenated with a pipe '|'. It will convert them back using the Split function, assuming your text value contains no other pipes.

Thursday, March 16, 2017

The first three tips have all been related to WPF data binding. Let's continue the theme with IValueConverter. IValueConverter is used in conjunction with the Converter parameter on a property's Binding.

Converters are used whenever the type of the property being bound does not match the type of the property in the binding source. Converting a boolean value to Visibility enum value is the most common conversion throughout all Xaml code. It is so common that the .NET Framework has its own BooleanToVisibilityConverter class that implements IValueConverter.

To implement your own converter, simply create a class that implements the IValueConverter interface. The interface has two methods, Convert() and ConvertBack(). If your property will never update its binding source, the ConvertBack() method does not need to be implemented. If you leave the default code Visual Studio puts in newly generated methods to throw a NotImplementedException, you will quickly find out if the ConvertBack() method is necessary for your converter.

This simple example is a variation on the BooleanToVisibilityConverter. It is an IndecisiveEnumToVisibilityConverter. Here is what my IndecisiveEnum looks like:

For the IndecisiveEnum.NotUnlessEveryoneElseIsDoingIt value, the case calls a method which we'll pretend calls a web service to find out if everyone else is actually doing it or not. If the input value is NotSure, then a random call will return either Visible or Collapsed. Converting back is a little more straightforward.

Consuming this converter in the WPF Xaml consists of two parts. First, the converter must be defined as a resource.

Monday, March 13, 2017

Let's take another look at using a FallbackValue in WPF. In Tip #2, it was used to provide a temporary value while waiting for an async data binding value to return from a slow-running ViewModel property getter.

A more common use of FallbackValue is in conjunction with MultiBinding. MultiBinding allows a single element's property to be bound to multiple objects on your data source (ViewModel, relative sources, etc.) If the values of the MultiBinding are unavailable or invalid, or use converters that return invalid results, the MultiBinding's FallbackValue will be displayed. This StackOverflow answer provides a great explanation with some examples.

The TextBox is now using a MultiBinding to return the original SlowText from last time as async plus some RichText property being converted to plain text with an RtfToPlainTextConverter that has been added to the project. If the bindings fail, the converters fail, or our async binding is really slow, the FallbackValue will be displayed in the TextBox.Text.

What is a converter, you ask? This sounds like a great subject for our next couple of WPF Tips. Stay tuned!

Sunday, March 5, 2017

In Tip #1, we examined how an IsAsync attribute can be added to WPF bindings to allow an application's UI to remain responsive while waiting for long-running ViewModel property getters.

It was mentioned that setting the FallbackValue on an object provides a way to put a default value into a property while waiting for the live data to populate through the ViewModel. This can be used to populate actual default values or to display some placeholder text to indicate to users that the live data is still loading.

Here is a simple example of using a FallbackValue with IsAsync on a standard WPF TextBox bound to a ViewModel property named SlowText.

Saturday, March 4, 2017

Welcome to a new series of quick tips for .NET desktop developers using WPF. Expect new tips (at least) weekly on this site. For links to other great resources for .NET developers, please check out my daily link blog, the Morning Dew.

IsAsync

The IsAsync attribute on a WPF data binding allows your UI thread to remain responsive to user activity while the property to which a control is bound is retrieving data. This can be useful if the application must fetch large amounts of data or when a slower database or web data source is invoked.

Here's a sample usage of the attribute on a simple ListView. This ListView gets a list of items from a user's media catalog and presents them in a simple grid format with headers.

While the data is being retrieved by the MediaCatalog's getter, a FallbackValue can be specified. In this case, a data row with a Title of "Loading…" could be used to indicate to the application's user that live data is on its way.