none
[UWP]Contentcontrol Datatemplateselector Bindings not updated on an underlying UserControl RRS feed

  • Question

  • Hi!

    I want to have an Element (Contentcontrol) to display different ViewModels with different Datatemplates. For Example ElementA contains a string and should be displayed as textbox and ElementB contains a boolean that should be displayed as switch. The element type can change at runtime, meaning I can switch from text/string view to button/boolean view.

    I used a datatemplateselector for this usecase. It works fine, unless I use an usercontrol inside one of the datatemplates. If the element changes, but the type (A or B) does not change, the usercontrol does not get recreated and so the binded viewmodel along with all its properties does not get updated properly. But if you switch to another datatemplate (B) and come back to A again, the usercontrol constructor gets called again. You can check that by adding a breakpoint into the Constructor of "MyUserControlA" in the attached example.

    To demonstrate the problem easier I've uploaded a minimal example:

    https://github.com/AtosNicoS/ContentControlDataTemplateSelectorProblem

    To reproduce the problem:

    Try switching between A1 and A2. You will see the usercontrol does not gets its binding updated, because the control itself is not recreated (breakpoint in constructor). Switch to B1 or B2 and then back to A1/2 and you will see, that the usercontrol gets recreated (constructor called) and updated properly.

    I do not want to use OneWay Bindings all the way down to my usercontrol, because that would be wrong. If I look at the usercontrol itself, the textblock inside should not be OneWay, just OneTime. So that is not an option here, even if you think that was a problem.

    I also tried the IValueConverter example from here, without luck: https://stackoverflow.com/questions/2085467/explicitly-refresh-datatemplate-from-a-datatemplateselector

    I had more luck with Bindings.Update() when setting the ViewModel, but that is still somehow a hack, and does not sound like a general solution.

    private void OnDataContextChanged(FrameworkElement sender, DataContextChangedEventArgs args)
    {
        Bindings.Update();
    }

    So please, what am I doing wrong, or is this maybe even a framework bug?



    Wednesday, September 11, 2019 8:12 AM

All replies

  • Hi,

    The problem is that you are using binding to bind the ViewModel to the DataContext of the UserControl.

    Like this:

    <local:MyUserControlA DataContext="{x:Bind MyUserControlAViewModel, Mode=OneTime}"/>

    For properties inside the ViewModel, we could call propertychanged event to notify the UI. But when you treat the DataContext as a property of the UserControl, there is no way for us to notify the UI when the DataContext is changed unlike we can do for the properties in the ViewModel using propertychanged event.  That's why when you using Bindings.Update(); in DataContextChanged could solve the problem. It tells the UI that the DataContext is changed and updated the Binding which is the same work with INotifyPropertyChanged interface.

    Generally, we use a ViewModel and consider it as a root container, we do all the works inside the ViewModel so we implement the INotifyPropertyChanged interface for the ViewModel. Then the changes could be shown in the UI. This is the best practice. So for your scenario, my suggestion is that do not binding the DataContext, create DependencyProperty used for binding directly to the ViewModel's property. 

    Like this:

       <local:MyUserControlA DependencyPropertyText="{x:Bind MyUserControlAViewModel, Mode=OneTime}" .../>

    If you don like this, you could still using Bindings.Update() in DataContextChanged event. For more information, please refer: Data binding in depth.

    Best regards,

    Roy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, September 12, 2019 3:30 AM
    Moderator
  • Hi Roy,

    thanks for the fast reply. If I understand correct, you suggest this change:

    https://github.com/AtosNicoS/ContentControlDataTemplateSelectorProblem/commit/bcac312df8361243bcac64f3117fa3529a294d97

    However it still does not work, same behavior. I might have missed something, maybe you can help out again.

    Cheers

    Nico

    Friday, September 13, 2019 11:20 AM
  • I think it's too complicated to implement his solution. If I were you, I'll use Bindings.Update(). It's a easy way to understand.
    Monday, September 16, 2019 9:57 AM
  • Hey Roy,

    any updates on this issue? I could not resolv it yet by your help. See my linked code.

    Monday, October 14, 2019 12:44 PM