Among the first things I covered in this blog was Localization. After I had finished those posts, I felt like I had covered everything one would need to write fully globalized applications. However, meanwhile I found out how to do some things better, and I’d like to share that here.
Making Localization Work at Design Time
One of the drawbacks of the original WPFGlue localization components was that they didn’t work nicely at design time. The reason was that I hadn’t found out how to automatically locate an application’s resources when the application was hosted inside the VS XAML designer.
The key here is a property on the Application class named ResourceAssembly. When the VS designer hosts an assembly, it will put a reference to it into this property, so the MarkupExtensions can locate the assembly that contains the current project’s resources.
Also, I revised the detection for the resource basename. The basename contains the project’s root namespace. One can find this as the namespace of the project’s Application class, which will normally be the project’s only class derived of System.Windows.Application.
I encapsulated this all into a new base class for the localization markup extensions:
Notice the fallback detection for the resource assembly: the first location is the application domain’s entry assembly. If the assembly isn’t running it’s own domain (because it’s hosted in the designer), the next location is the ResourceAssembly. As before, one can override the resource assembly by setting the Localization.ResourceAssembly attached property.
By the way, in the post "The Last Word on Localized Resources" I suggested using a localized URL in order to use different localized ResourceDictionaries in ones XAML files. I don’t recommend this approach any longer. While it works at run time, the designer experience is bad: one will get squiggly lines telling that the resources can’t be found, and one cannot see the values of the resources in the designer panel. With the new markup extensions based on the above class, one will have instant feedback.
Funny enough, VS will use the set of resources that match its own language version. So, running US-English Microsoft Visual Basic 2010 Express on German Windows, I see the English localization in the designer and the German localization when I start the debugger.
How to Use Bitmap Resources
Another thing I learned is how to convert from System.Drawing.Bitmap, which is what one gets from the ResourceManager when one accesses an image resource, to System.Windows.Media.Imaging.BitmapSource, which is what the WPF Image control expects:
The conversion happens through a shared bitmap handle, so I assume it’s not too heavy on memory consumption. As a nice side effect, one can now use PNG images without them being unaccountably scaled to 133% their pixel size. Also, the images will now instantly be visible in the designer.
How to Create Alternative Resource Files
In my first post about localized resources, I described a kind of complicated procedure for creating resource files for alternative languages. A somewhat simplified procedure, which goes without closing the IDE, is as follows:
- Complete your application, creating resources in the My Project / Resources designer as you go.
- When done, activate the “Show All Files” icon in Solution Explorer.
- Locate the Resources.resx file in the My Project folder and create a copy of it. You can do this using the context menu in Solution Explorer. The copy can be located anywhere in your project directory. Probably you should keep it outside the My Project folder.
- Rename the copy to reflect the intended language and culture, e.g. to Resources.de.resx for general German, or Resources.ar-SA.resx for Arabic (Saudi Arabia). At that stage, you can deactivate the “Show All Files” switch again.
- Double click the file in order to open it in the resource designer.
- Make sure that the Access Modifier is set to “No Code Generation”.
- Replace the original resource strings and icons with the appropriate translations.
- Make sure that the Neutral Language in My Project / Application / Assembly Information is set to the language you used for the original version of the resources.
While support for .Net resources is completely missing from WPF, one can create an experience that feels equally nice at design time and at run time by using some simple custom markup extensions.
A Command in WPF encapsulates a method to do something, a check on whether it is possible to do it at the moment , and a notification of when that state changes. It does this in a way so that one can bind a control like a Button or MenuItem to a command, and the control will execute the command when clicked and enable and disable itself according to whether the command is available.
WPF supports this infrastructure through two APIs: CommandBindings, which can be defined in XAML, but can only call methods defined in the XAML’s code-behind file, and the ICommand-Interface, which can be implemented in ViewModel classes, and supports creating properties in the ViewModel which allow to bind a control to a command.
For the first approach, I don’t like that I have to write code in the code-behind file. Defining a command is a routine thing, so I’d like to do it in XAML.
For the second approach, I don’t like that I have to implement an interface, and create kind of standard boilerplate glue-code in order to be able to make the UI call a method in the model. If possible, I want to do all the gluing that is necessary in XAML only.
What would an ideal solution look like? I’d like to have a way to just take any normal method in the ViewModel, bind a command to it (that would be a RoutedCommand object, like with the CommandBinding approach), and assign the RoutedCommand to any Control that supports commands.
In the post about the Sticky Command Design Pattern, I have already demonstrated how one can set up CommandBindings through attached properties. Now, I want to generalize this approach into a commanding framework.
A Reusable Sticky Command
The first element is a reusable component which ties a RoutedCommand and its implementation together. Basically, it contains the same information as a CommandBinding, and in fact it is just a wrapper and adapter which is responsible for creating CommandBindings while overcoming their limitations.
So, on the one hand, the Command class defines the usual Attach and Detach methods for Sticky Components:
Command here is a property which holds a RoutedCommand and which can be configured through XAML. UseValidation and Preview are also properties which can be configured through XAML.
On the other hand, the Command class defines standard implementations for the CommandBinding’s Executed and CanExecute delegates:
This code contains some details which I am going to cover in later posts. The important thing for now is: there are standard event handlers which can be attached to a CommandBinding, and their real work is done in the overridable Execute and CanExecute methods. These methods are supposed to be implemented by derived classes.
Binding to Methods
So far, we have an object which can create a CommandBinding by attaching itself to a Control. The next step is to bind a method of our ViewModel to this object.
For this purpose, I created a subclass of Command, ActionCommand, which defines a property of type Action, i.e. a Delegate for a method that doesn’t take parameters and doesn’t return a result.
The class overrides the Execute method with an implementation that invokes the method the ExecutedAction delegate is bound to.
In order to be able to bind a value to the ExecutedAction delegate, I created the property as a DependencyProperty. Also, I derived the base class for my Command from Freezable. Freezables are special objects that are optimized for use as resources. What makes them extremely useful in our case is that they inherit the DataContext of the FrameworkElement in whose Resources section they are defined. The DataContext will be our ViewModel object. So, the only thing lacking is a way to create a Delegate for one of its methods through a Binding.
The solution here is a converter. The special converter we use in this case will accept the name of the method as ConverterParameter. Then it will inspect the type of the bound property and the type of the bound object in order to create a Delegate with a matching signature. This is its code:
And the method which creates the Delegate:
Gluing it Together in XAML
While this looks quite complex, the good news is that one needs to create this kind of class only once, and from then on can use it to bind to method in XAML only. This is how one would define a Command which binds to a method in the ViewModel:
In this case, the we use the predefined Open RoutedCommand, and bind it to a method called Open (as specified by the ConverterParameter in the Binding) on the current DataContext. Instead of the predefined Open command, we could use any RoutedCommand, even those defined in our own application.
We connect the command to a Control using a Sticky Property which the commanding framework defines:
As you can see, the Button which triggers the command is completely unaware of its implementation: it just knows that it should work with the Open predefined command, and the rest works through the WPF RoutedCommand infrastructure. This means that you can also take advantage of command routing, like having a MenuItem triggering the same command on different controls depending on which control has keyboard focus. This is more than one gets using the traditional MVVM RelayCommand approach.
Even though it is a bit of work, it is possible to create reusable components which allow it to bind a RoutedCommand to a method of a ViewModel using XAML only. With this technique, it is possible to take advantage of WPF command routing, while at the same time the amount of glue code in the ViewModel is reduced.
You can find the full code and an example project, CommandingExample, in the WPFGluePublished download through the Downloads page.
In posts to come I will cover more details of the WPFGlue Commanding framework, like executing commands on background threads, displaying status and exception messages, or defining CommandSets in order to attach several commands in one line of XAML.
It’s been a long time since I have written in this blog. The reason is: there have been many changes in my life during the past two years, and I simply haven’t found the time until now. Anyway, I’ve been checking out things and learning continuously, and I hope to be able to share these things more regularly in the future.
In the last post, Validating Objects with ValidationRules, I proposed a way to define ValidationRules for an object in one location and to set them on all Bindings that need them through a single attached property.
Today, I want to show how to set up basic type checks automatically. The example code is contained in the ValidationExample project in the source code distribution, which you can access through the downloads page.
How WPF handles Type
Normally, if the value entered in a TextBox cannot be converted into the type of the bound property, e.g. if you enter letters into a TextBox expecting an integer value, first of all there will be a runtime exception. By default, WPF will handle this exception, mark the TextBox as having invalid data, and assign a default “Conversion error” error message to it. Since the value cannot be converted, WPF will not update the bound property, which means that it will keep its value unchanged.
The first level of refinement here would be to allow the Binding to display exception messages by setting ValidatesOnExceptions to true. Now, if changing a property causes an exception, Validation.Errors will contain the exception’s message. Now the user will at least know whether the reason for the exception is a type mismatch or a numerical overflow.
Validation as a User Interface Responsibility
Why is this not enough?
Reusable software components like services or libraries need to check their input and throw exceptions if it is invalid. This is how one piece of software tells another piece of software that it has done something wrong.
User Interfaces, which basically translate between human users and the software they want to use, are responsible for making sure that those users only provide valid input values. The best way to do that is to offer only valid options to the user. Where that isn’t possible, validation steps in by providing explicit and meaningful validation messages which tell the users what they have to change in order to achieve the intended result.
As a rule of thumb, I’d say that one should protect one’s services and libraries by throwing exceptions, and that one should use validation in the UI to make sure that those exceptions never get thrown.
So, while exceptions are directed at technically aware developers debugging their software components, validation messages are directed at end users with possibly no technical background at all. For example, the error message you receive when you enter too many digits into the TextBox that validates with exceptions in the example project, reads: “Value was either too large or too small for an Int32”. This is obviously not what one would display to a user who has never heard of Int32.
Therefore, in the user interface, one would need two functionalities:
- a way to provide globalized validation messages independent of the system’s exception messages.
- a way to keep WPF controls from trying to update properties with values of non-matching type.
The TypeValidationRuleSetter Class
The TypeValidationRuleSetter class is a subclass of the ValidationRuleSetter class I mentioned in the last post. In addition to adding predefined ValidationRules to specified properties on a bound object, it will inspect the object’s type, find out the primitive CLR-type of a bound property, and will add default validation rules for each type which use XAML-configurable validation messages.
At the heart of the TypeValidationRuleSetter class is the following method:
This method will be called during the Initialized event, when Bindings have been established but still can be modified. It inspects the type of the property and adds one of a choice of default ValidationRules, which basically make a difference only between date, integer and other numerical values, providing different value ranges as feedback to the end user. So, the class translates from the technical, physical representation, which is determined by the CLR type of the property, to the logical limitations that type entails, which is what is relevant for the user.
So, although there are different checks for different allowed value ranges, there are only three configurable, i.e. localizable, validation messages:
The default ValidationRules use basic .Net functions in order to determine whether .Net can convert the value:
Finally, the allowed minimum and maximum values are formatted into the validation message, to give the users complete feedback on what they have to enter in order to make it a valid value:
The TypeValidationRuleSetter class allows it to include meaningful and localizable validation messages for type checks with minimal effort. At the same time, it protects the application from exceptions which would otherwise be thrown because of type mismatches between what is entered into a TextBox and the type of the bound property.