Blog

Martin Martin
28.03.2016 13:43

The bad side of UWP


The bad side of UWP

I'm a frontend developer using WPF with .net 3.5 since 2009. So I would say I know a thing or two about WPF but lately got a little bit rusty, because the last year most of the projects I was assigned were web related. Therefore, I was really excited about my first UWP project app. My personal goal and interest regarding this UWP project were to find ways to adopt the WPF best practices. The result and experience is described below. Needless to say, UWP got its upsides, but on this article I will focus on the frustrating stuff.

Silverlight developers might not be as bothered as I am by the limitations that UWP entails, due to the fact that they seem to be somewhat used to the restriced XAML subset. I on the other hand am accustomed to being able to make use of the full WPF XAML possibilities.

Styles, x:Type, x:Static

Letís start and compare WPF and UWP projects. I like the MVVM pattern and when I'm able to put UI logic into XAML code, I do so.

For example, when our task is to display additional controls on a checked checkbox we can handle all of this UI logic in XAML. I did this in WPF XAML with style triggers and in some cases using animations to set values on specific events. In UWP you can't do this anymore. Style triggers are gone.

Luckly, there is a workaround and a complete implemented solution using the "Behavior SDK (XAML)". See the code below. 

Regardless, the Behavior Attached Propertie works only on controls and cannot be used in styles. The next thing I realize was that x:Type and x:Static are also not available in UWP.

I used x:Static in WPF for many cases, but letís focus on styles. We could have done something like that with WPF styles in our Resource:

With the above code, we "inherit" the base TextBox style and set the Background Property to green. In UWP we can't "inherit" the base TextBox style, because of the two missing Keywords. The only workaround I know for this issue feels a little bit nasty.

We could copy the default control styles from \(Program Files)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\10.0.10586.0\Generic and copy it to our ResourceDictionary and assign a Key to every style. So we could use the BasedOn Property.

x:Static is used in WPF to "access" static members from XAML and is, as I mentioned before, gone in UWP.

Localization

The way how localization is done in UWP also changed. At the moment I'm not quite sure if the result is satisfying.  Anyway, in UWP you got resw files. A localization in UWP can looks like the following:

Lets assume the resw file contains the following key(s):

Abort.Content Abort
Abort.ToolTip Aborts the current operation

The last part of the key contains a dot followed by the Name of the property which the value should be assigned to. This means for the above example that the Button's property Content is "Abort" and the ToolTip contains "Aborts the current operations". This gives us the ability to use x:Uid on a control once, but it can localize multiple Depdency Properties. On the other hand, I have to create a new Key "Abort.Text" when I want to use the Value "Abort" for the TextBlock DP Text.

TypeConverters

So far the localization in UWP seems to be better supported than in WPF. But letís take another look at the restricted XAML capabilities. TypeConverters are a very important. You can use them for types such as: arrays, strings, brushes and double and so forth in XAML code. The existing TypeConverters support only a little subset of those Types. So I thought, no problem, Iíll create my own TypeConverter for the unsupported ones, but no, you canít even extend or add additional TypeConverters.

Iíll give you an example of how deeply these missing TypeConverters affect existing best practices. There are two proper ways to handle user privileges in a WPF application. One of them is implemented with converters.

Letís see the simplified example below:

In this example, the ConverterParameter contains a Sorted Dictionary in XAML, which defines the required claim for the current WindowsIdentity to show the MenuItem. The ClaimConverter evaluates if the current Principal contains the necessary claims defined by the ConverterParameter and returns the proper Visibility. Because I can't use the SortedList in XAML the whole concept is useless.

Some workarounds can be found here http://stackoverflow.com/questions/12495937/winrt-replacement-for-system-componentmodel-typeconverter

Custom Controls

The limited TypeConverter ability also concerns the custom control development. Which brings me to the next point: creating custom controls. Routed Events like the ones in WPF are, you guessed it, also gone! As a workaround I created a DP which uses a DelegateCommand which in return can be manually raised. Sure, it's no replacement for the routed events. Theyíve got the cool routing strategies like bubbling and tunneling features. Also, we only got a stripped down version of the DependencyProperties compared to WPF ( http://WPF.2000things.com/tag/dependency-properties/)

Validation

When you develop WPF applications the possibility that you get in touch with validation is quite high. The WPF validation is mostly done using Adorners in combination with IDataErrorInfo or BindingValidationError. The Adorners give you the ability to set the state of a control visually. Because in UWP this element doesn't exist anymore, I looked again for an UWP workaround.

Using Prism I quickly found the solution in a pattern and practice example: https://msdn.microsoft.com/en-us/library/windows/apps/xx130660.aspx?f=255&MSPPError=-2147217396. What are they doing? Simplified, the solution is using attached properties where you set the default and a validation style. When the value gets invalid it uses the validation style which you set on the attached property. Most of the time you only want to add a red border to the invalid control and print the error message. When using this approach you have to create additional styles that define the appearance of the control when it is invalid.

Another way to solve this validation issue is to create a usercontrol that "hosts" the control which needs to be validated. The usercontrol shows the red border with the validation message when needed. I think something like that is done here http://blog.jerrynixon.com/2014/07/lets-code-handling-validation-in-your.html. Maybe a combination of the pattern and practice with jerry nixons approach can work as a fine solution.

Last but not least

There are quite more features which I'm missing in UWP like multibindings, no IMultivalueConverter, using the ancestor type in bindings and so on, but the above ones are the most important in my opinion.

What concerns me most in UWP is that the flexibility is gone.

One of coolest things when taking the full advantage of WPF was to create nearly any kind of control really fast.  The missing features definitely dampen my view of UWP as a whole.

There is a discussion https://github.com/dotnet/corefx/issues/5766on github related to the XAML topic. Maybe when the System.XAML Namespace will be opened we can add the missing features by ourselves.

Some of the aforementioned issues are already being discussed on the uservoice platform:

 

What do you think about UWP? Are you currently developing in UWP and are you ok with how it turned out? Did you find workarounds for the XAML limitations by yourself? I would be glad to hear from your UWP experience.


: UWP, XAML, WPF, c#
: 02. April 2016 09:18
Link zu diesem Artikel: (in die Zwischenablage)