xamlmvvmwinui-3winui

WinUI 3 Frame not Binding


I have created a problem with binding my View's Frame with the ViewModel's Frame encapsulating property. What is happening (without any errors or application crash), is when I select a NavigationView's Item (NavigationViewItem), it executes fine, and binds to the ViewModel accordingly. The View's Frame UIElement does not respond to the changes. Am I binding to the wrong property?

My View:

<NavigationView MenuItemsSource="{x:Bind p.ViewModel.GetNavigationViews}"
                    ItemInvoked="{x:Bind p.ViewModel.ItemInvoked}">
        <NavigationView.Content>
            <ScrollViewer>
                <Frame DataContext="{x:Bind p.ViewModel.ContentFrame}"/>
            </ScrollViewer>
        </NavigationView.Content>
    </NavigationView>

My ViewModel:

public Frame ContentFrame { get; set; } = new();

My Presenter:

 public class MainPagePresenter : PagePresenterBase<MainPageView, MainPageViewModel>
{
    public MainPagePresenter() : base()
    {
        ViewModel.ItemInvoked = new(ItemInvoked);
    }

    void ItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args)
    {
        FrameNavigationOptions options = new()
        {
            TransitionInfoOverride = args.RecommendedNavigationTransitionInfo
        };
        if (sender.PaneDisplayMode == NavigationViewPaneDisplayMode.Auto)
        {
            options.IsNavigationStackEnabled = false;
        }

        Type pageType = null;

        switch (args.InvokedItem)
        {
            case "Subscriptions": pageType = typeof(SubscriptionsView); break;
            case "Account Link": pageType = typeof(AccountLinkView); break;         
        }
        ViewModel.ContentFrame.NavigateToType(pageType, null, options);
    }   
}

Solution

  • Setting the DataContext is something like setting data in the background for bindings. So, in your case, you need to set ContentFrame as ScrollViewer's Content.

    <NavigationView
        ItemInvoked="{x:Bind p.ViewModel.ItemInvoked}"
        MenuItemsSource="{x:Bind p.ViewModel.GetNavigationViews}">
        <NavigationView.Content>
            <ScrollViewer Content="{x:Bind p.ViewModel.ContentFrame, Mode=OneWay}" />
        </NavigationView.Content>
    </NavigationView>