(published on 11/30/2015, although WordPress states ’11/15/2015′)
Intro
The first time I heard about Compiled Bindings (x:Bind) was at Build 2015. Finally we got compile-time validation on bindings and it promised to be a lot faster as it doesn’t need to do reflection at runtime! After playing around with it for a bit, I introduced it to my development team and we were going to use it wherever possible in our UWP project.
Once we were using it in real-life scenarios we stumbled upon some issues with compiled bindings. Luckily all these issues were apparently due to the fact we were developing against very early bits of UWP because since the launch of 10.0 Build 10240 these issues were gone… All except for one…
And it’s kind of an annoying one.
The problem
Let me illustrate.
I’ve got two interfaces: IViewModel (exposing a Title property) and IMainPageViewModel which inherits from IViewModel.
I’ve got a Page that has a property ViewModel of type IMainPageViewModel.
On my MainPage, I try to bind the Title property of my IMainViewModel (which is inherited from IViewModel) to a TextBlock.
But, at compile time, Visual Studio throws the following compilation error at me:
Invalid binding path ‘ViewModel.Title’ : Property ‘Title’ can’t be found on type ‘IMainPageViewModel’
It turns out, only properties of the interface you are binding on directly can be found. Properties of an interface that are inherited from an other interface can’t be found.
A solution
We could get this to work by explicitly exposing the Title property on the IMainViewModel.
But, as you can see in the above image, Visual Studio gives us a warning. If we want to do this in a ‘clean’ way, we could use the ‘new’ keyword as Visual Studio suggests.
Thoughts
IMHO, this is dirty… Hiding inherited members can be useful in some situations, but not in this scenario for compiled bindings. The binding engine should in fact recognize the members of all underlying interfaces. Imagine you need to expose a handful of properties from your base IViewModel, the interfaces of our ViewModels won’t look pretty.
Sadly, at this moment, I don’t see any other options. However, despite it being dirty, it does work. For now, we will need to keep ‘hinting’ the binding engine for these properties we inherit from underlying interfaces. Hopefully Microsoft fixes this over time…
November 30, 2015 at 11:04 am
An alternative is to have two fields on your page/control for the two different interfaces/objects and bind to whichever is relevant. For example https://github.com/MediaBrowser/Emby.Mobile.Universal/blob/Dev/Emby.Mobile.Universal/Controls/ItemControls/UserDtoControl.xaml.cs#L9-L10
December 27, 2017 at 4:08 pm
Window Template Studio using MVVM Light allows you to x:Bind to ViewModel which is provided by its Locator service. It allows you to do the following:
Text=”{x:Bind ViewModel.MyText }”
The syntax is a bit wordy, but get’s the job done.