The NuGet package has been updated so if you’re using the Xaml Behaviors in your app, all you need is to let NuGet take the latest version of the package!
In the next days I’ll be releasing a new version of the Cimbalino Toolkit to take this updated Xaml Behaviors package.
Update 24/02/2016:
I forgot to mention a massive difference on the new version of the XAML Behaviors:
If you use PowerShell to output the Assembly Full Name from the current and previous versions of the XAML Behaviors, this is what you will get:
Most programming language allow you to take advantage of multi-threaded execution, and .NET is no exception!
Asynchronous code is a modern abstraction of multi-threading execution, and as you hopefully are aware, in .NET land, this is achieved with the async and await keywords.
For the Universal Windows Platform, we can also count on the CoreDispatcher class to marshal execution back to the main thread, from which we can update the UI of our apps.
Here’s a simple example of how to use it:
publicasyncvoidDoStuff()
{
var dispatcher = CoreApplication.MainView.CoreWindow.Dispatcher;
Assuming we are on a background thread when the DoStuff() method is invoked, we will retrieve a CoreDispatcher instance from the CoreWindow.CoreDispatcher property, call and await for the execution of dispatcher.RunAsync() method, which in turn will invoke the UpdateUI() method on the main thread, and then code execution will continue in the background thread by invoking the DoOtherStuff() method.
As it is right now, we know that DoOtherStuff will only execute after the UpdateUI() method finishes, but now let’s assume that we replace the UpdateUI() synchronous method with an asynchronous version of it, called UpdateUIAsync():
publicasyncvoidDoStuff()
{
var dispatcher = CoreApplication.MainView.CoreWindow.Dispatcher;
In this new version of the code, you’ll notice that the DoOtherStuff() method will eventually run before the UpdateUIAsync() has finished, which might not be what you intended to in the first place when you await’ed for the dispatcher.RunAsync() method!
The fact that we’ve added the async/await keywords to the callback doesn’t ensure that the caller will await for it to execute!
There are a few ways suspend the background thread execution until the foreground thread signals for it to continue, and using a TaskCompletionSource<T> is one of the easiest:
publicasyncvoidDoStuff()
{
var dispatcher = CoreApplication.MainView.CoreWindow.Dispatcher;
var taskCompletionSource =newTaskCompletionSource<bool>();
In this version of the code, once the execution returns from await’ing the dispatcher.RunAsync() call, the background thread will carry on execution, but will then await for the taskCompletionSource.Task to finish, which will only happen after the taskCompletionSource.SetResult(true) call that we make in the main thread!
A few months ago I wrote my first Compiled Bindings considerations article, and seems that time has come to write some more, only this time I’m bearer of some bad news…
TL;DR
Compiled Bindings have a bug, noticeable in some scenarios, specifically when a binding has a fallback value of null (which is the default)!
Make sure to thoroughly test your app if you use compiled bindings!
So what is the big deal?
To illustrate the problem, I’ve written a small demo app!
ViewModelBase is just a standard implementation for the INotifyPropertyChanged interface, providing an OnPropertyChanged helper method to its inheritors.
MainViewModel will be used as the main view model for our sample and has a single property, CurrentTime.
CurrentTimeViewModel has a single CurrentTimeTicks property which will contain a string representing the current time in ticks; an Update helper method has also been added to this view model.
As you can see above, we create a new MainViewModel instance, set it as the page DataContext property, and then we have the three click event handlers, one for each of the buttons on the view.
We’ve also added a MainPage.ViewModel property to expose the current MainViewModel instance to the compiled bindings (we can’t use the DataContext property as its type is object and compiled bindings require strong-typed properties to work).
This is what you’ll get if you run the app and tap the buttons in succession:
As you can see, the 2nd TextBlock (the one using compiled bindings) never gets the text cleared when we tap the “Destroy CurrentTimeViewModel” button!
The expected behavior is the one shown in the 1st TextBlock: if the binding value is null or unavailable, the TextBlock.Text property will set to the Binding.FallbackValue (which is null by default).
So after checking the documentation for compiled bindings, one can say without that compiled bindings are ignoring the fallback value when its value is null, and that is quite a nasty bug in the compiled bindings!
This bug has already been reported to Microsoft but as we don’t know when it will get fixed, all we can do right now is be aware of the whole issue and make sure to test our apps thoroughly to ensure we don’t end up with these problems after migrating to compiled bindings!
.NET Native behaves just like that expensive restaurant you love to got to: you have to wait until you finish the meal to see how much it will cost you - and it will definitely cost you!
Last weekend I was confronted with a bug in Cimbalino ToolkitMultiBindingBehavior, which caused apps using it to crash when they were built in Release mode!
I built a small test app and after a couple of minutes debugging it I noticed a MissingMetadataException getting raised; the culprit was found: .NET Native!
If you’re working with Universal Windows Apps (UWP) and don’t know what .NET Native is, I strongly advise you to start by reading the following excellent articles written by Morgan Brown, “a Software Development Engineer on the .NET Native team”:
Here’s the situation right now: when you build a UWP app, the compiler will do some “smart stuff” with your code (let’s skip the technicals here!), squeezing every little bit it can to make sure the compiled result will perform better and faster!
But there is a catch: if your code uses any type of dynamic coding features such as reflection or serialization, you might need to instruct the compiler that certain types in your application will be used as such, in order to avoid the exceptions like the MissingMetadataException you see above.
To avoid such problems, you can add specially built rd.xml files to your project - once again, check the articles above for more information on this subject!
The MultiBindingBehavior works by using the AssociateObject property value to reflect and dynamically create a binding expression, so what I needed was to ensure that it would be able to reflect any object passed to this property.
With this requirement in mind, I created a new Cimbalino.Toolkit.rd.xml file, set its Build Action to Embedded Resource, and set the content to the following:
Aaand… this didn’t work! I started getting a build error message stating that it couldn’t find any AssociatedObject property in the Cimbalino.Toolkit.Behaviors.MultiBindingBehavior.
Granted, the property does not exist directly in this class, but rather in the Behavior<T> base class, so I guess one say that .NET Native compilation completely forgot a completely basic feature of .NET and most object oriented languages: Class Inheritance!
Taking this into account, I made a couple of changes in the file and here’s what in the end made it work:
When working with Universal Windows Apps, make sure to build the app in Release mode and test it thoroughly!
Keep an eye out on the build warnings for any problems with your rd.xml files.
If you’re working with MVVM or have Model representation classes, it might make sense to put these in a separate assembly, or at least in a separate namespace from the rest of the code - this will allow you to easily target these files in a rd.xml for .NET Native optimization exclusion.
They were kind enough to keep me in the loop and that allowed me to prepare for the incoming changes! ;)
Cimbalino Toolkit 2.1.0
Version 2.1.0 of the Cimbalino Toolkit is a basic update of the toolkit with a few improvements and bug fixes, but takes into account the new XAML Behaviors:
UWP apps it now will pull the XAML Behaviors Managed NuGet package to the projects
non-UWP apps will still use the NuGet PowerShell scripts to add the Behaviors SDK
Do notice that while the Interaction class in the XAML Behaviors now performs the proper attach/detach pattern, the same can’t be said for the Behaviors SDK Extension for non-UWP apps, so I strongly advise you to keep using the MonitoredInteraction class for those projects!
One final note: if you actually want to use the XAML Behaviours, you will have to actually manually add the NuGet package to your project… this is due to the new Transitive Dependencies feature of NuGet 3.x, and as far as I know, there is no way of going around this extra step!
Since the very first versions of the .NET Framework, developers had the System.Globalization namespace “containing classes that define culture-related information, including language, country/region, calendars in use, format patterns for dates, currency, and numbers, and sort order for strings.”
One of the most useful classes in this namespace is the CultureInfo class!
To demonstrate the usage of this class, take a look at this really simple console app code:
As you can see from the above results, the CurrentCulture and CurrentUICulture property values are inferred respectively from Regional Settings and Display Language; the Location however, doesn’t seem to have any effect over these two properties.
This feature allowed any app to show data using the proper currency, date, and number formats, even if the app itself wasn’t localized for those cultures!
But then came WinRT with the Windows.Globalization namespace as a replacement, and that apparently affected the way the CultureInfo class behaved…
To show the differences, I’ve created a blank Windows 8 app, and set the following code in the MainView.xaml.cs file:
As you can see here, both the CurrentCulture and CurrentUICulture property values are now based on the selected Display Language!
In my personal opinion, this change of behavior is wrong for various reasons, but mostly because it breaks the expected known behavior of the CultureInfo class properties.
Right now you might be thinking that the impact of this change is really small, but it might actually be bigger than expect due to a specific feature: Cortana!
As of today, Cortana is still only available in a few locations, and as such, most users have “faked” their location in order to get Cortana active on their devices, but maintained the Regional Settings matching their real location!
Retrieving the “proper” CurrentCulture
One could use the Windows API GetUserDefaultLocaleName to retrieve the Regional Settings, but this only works on full Windows 10, so it’s not a “universal” way of doing it!
However, I’ve found that if you create a DateTimeFormatter instance with “US” as language, you can retrieve the culture name from the DateTimeFormatter.ResolvedLanguage property!
And here is a simple code example demonstrating how to do it:
usingWindows.Globalization.DateTimeFormatting;
publicclassCultureInfoHelper
{
publicstaticCultureInfoGetCurrentCulture()
{
var cultureName =newDateTimeFormatter("longdate",new[]{"US"}).ResolvedLanguage;
returnnewCultureInfo(cultureName);
}
}
I honestly still don’t know how or why does this work with that Magic String™ (others might also do the trick though), but it does, and at this stage all I care are positive results!
So there you go, this is a nice hack to retrieve a CultureInfo instance for the Regional Settings, which you can then use to parse and format values in your UWP (and WinRT) app! :)
Attached Behaviors have been around for quite a while, and though I personally always liked them, they have a fundamental flaw: they can lead to huge memory leaks!
I’ve seen quite a few fixes for them (like this one from MVP Joost Van Schaik), though none proved to be truly “universal” and final!
To demonstrate the problem, let’s take a practical example:
create an app with two pages
page 1 will have a button to navigate to page 2
page 2 will have a button that when clicked, will navigate back to page 1 after a pause of 2 seconds
As you can see above, the button is binded to the Page2ViewModel.DelayedGoBackCommand. Also, we will be using an EventTriggerBehavior to monitor the Page2ViewModel.GoBack event, and when it gets raised, we will use the CallMethodAction to invoke the Page2.Frame.GoBack method.
Now here’s the catch: while behaviors have a way of being notified when they are to be detached, that never happens!! Not when you leave the page, not when the page gets unloaded, and not even when garbage collection runs.
As such, when we navigate back from page 2, Page2ViewModel.GoBack event will still hold a reference to the EventTriggerBehavior, leading to a memory leak!
But things get even worse in this example: everytime we navigate to page 2, we will subscribe over and over again the GoBack event, so multiple invocations will eventually occur - definitely not what we wanted!
The MonitoredInteraction was built as a direct replacement of the Microsoft.Xaml.Interactivity.Interaction, and will monitor the attached object Loaded and Unloaded events and call for the attachment and detachment of all behaviors it contains!
Here’s how page 2 view would look if put it to use:
Really, really simple, yet it will finally ensure that behaviors do get detached when one navigates away of a page, and re-attached when navigating in!
Hopefully someone from the Behaviors SDK team will read this, and take some of the suggestions here to fix this well known issue that’s been around for quite a while! ;)
As you’re probably aware, Windows 10 introduced a new type of Bindings called Compiled Bindings.
And as the name might suggest, compiled bindings are a way the compiler uses to generate static code for a binding instead of using a reflection based solution, as regular bindings do.
The main advantage is quite obvious: there will be a performance gain for using static compiled code instead of using reflection!
Let’s take a look at a simple regular binding example:
<TextBlockText="{Binding Name}"/>
This binding will set the TextBlock.Text property to the value of the Name and will update it every time the Name property changes (assuming that the data context implements and raises the necessary INotifyPropertyChanged.PropertyChanged event)
To take advantage of the compiled bindings, one would rewrite it like this:
<TextBlockText="{x:Bind Name, Mode=OneWay}"/>
Notice that I added the Mode=OneWay on the expression above?
Well, that is actually required due to a fundamental difference between regular bindings and compiled bindings: while the regular bindings default mode is OneWay, compiled bindings default mode is OneTime!
This is a really important piece of information that I’ve seen a lot of developers not taking notice, so make sure to fix those binding expressions correctly when you migrate to compiled bindings!