'Binding Callback Function to a HeaderTemplate

How do I bind a callback function to a DataTemplate inside a HeaderTemplate in WinUI3? After reading various answers it appears the DataContext inside a HeaderTemplate is different than throughout the rest of the XAML file.

The callback function is defined in the AM2BasePageViewModel class, which is called in the AM2BasePage constructor as such:

    AM2BasePage::AM2BasePage()
    { 
        m_am2BasePageViewModel = winrt::make<bionet::implementation::AM2BasePageViewModel>();
        InitializeComponent();
    }

Trying out various things, the relevant part in my XAML file now looks like this:

    <muxc:NavigationView  x:Name="NavigationView"
                        SelectionChanged="NavigationView_SelectionChanged" 
                        AlwaysShowHeader="True"
                        Canvas.ZIndex="0"
                        Header="s"  
                        IsBackButtonVisible="Collapsed"
                        BackRequested="NavigationView_BackRequested"  
                        Background="Transparent"
                        IsSettingsVisible="True"
                        Margin="0">
        <NavigationView.HeaderTemplate>

            <DataTemplate x:DataType="local:AM2BasePage" >
                <CommandBar x:Name ="AM2BaseCommandPanel" HorizontalAlignment="Left" HorizontalContentAlignment="Left">
                    <CommandBar.PrimaryCommands>
                        <AppBarButton x:Name="AM2BaseCommandPanelLoad" Icon="Document" Label="Attach Camera"/>
                        <AppBarSeparator />
                        <AppBarButton x:Name="AM2BaseCommandPanelRunSimulation" Icon="Play" Label="Like" Click="{x:Bind AM2BaseViewModel.RunSimulation_click, Mode=OneWay}"/>
                        <AppBarSeparator />
                    </CommandBar.PrimaryCommands>
                </CommandBar>
            </DataTemplate>
        </NavigationView.HeaderTemplate>

        <muxc:NavigationView.MenuItems>
            <muxc:NavigationViewItem Content="Home" Icon="Home" ToolTipService.ToolTip="Home"/>
            <muxc:NavigationViewItem 
                    x:Uid="AM2BasePage_NavigationViewItem_Values"
                               Icon="Page2" ToolTipService.ToolTip="Collections">
                <muxc:NavigationViewItem.MenuItems>
                    <muxc:NavigationViewItem 
                            Tag="bionet.AM2BasePageInitialValues"
                            x:Uid="AM2BasePage_NavigationViewItem_Values_InitialValues"
                                     ToolTipService.ToolTip="Bookshelf"/>
                    <muxc:NavigationViewItem
                            Tag="bionet.AM2BasePageParameters"
                            x:Uid="AM2BasePage_NavigationViewItem_Values_Parameters" 
                                     ToolTipService.ToolTip="Mail"/>
                </muxc:NavigationViewItem.MenuItems>
            </muxc:NavigationViewItem>
        </muxc:NavigationView.MenuItems>
        <Frame x:Name="ContentFrame">

        </Frame>
    </muxc:NavigationView>

The relevant part is Click="{x:Bind AM2BaseViewModel.RunSimulation_click, Mode=OneWay}".

This compiles but immediately crashes my program upon clicking the command bar with

Exception thrown at 0x00007FFCDA4C4F69 (KernelBase.dll) in bionet.exe: WinRT originate error - 0x80004002 : 'No such interface supported'.
Exception thrown at 0x00007FFCDA4C4F69 in bionet.exe: Microsoft C++ exception: winrt::hresult_no_interface at memory location 0x0000009728D5A198.
Exception thrown at 0x00007FFCDA4C4F69 in bionet.exe: Microsoft C++ exception: [rethrow] at memory location 0x0000000000000000.
Exception thrown at 0x00007FF6EBE9A039 in bionet.exe: 0xC0000005: Access violation reading location 0x0000000000000000.

I assume I do the callback function binding wrong. How can I call the callback function without the program crashing?

Edit: The AM2BasePageView header looks as such:

#pragma once
#include "pch.h"
#include "AM2BasePageViewModel.g.h"


namespace winrt::bionet::implementation
{

    struct AM2BasePageViewModel : AM2BasePageViewModelT<AM2BasePageViewModel>
    {
    public:
        AM2BasePageViewModel();

        void RunSimulation_click();

    private:
        winrt::event<Microsoft::UI::Xaml::Data::PropertyChangedEventHandler> m_propertyChanged;
    };
}
namespace winrt::bionet::factory_implementation
{
    struct AM2BasePageViewModel : AM2BasePageViewModelT<AM2BasePageViewModel, implementation::AM2BasePageViewModel>
    {
    };
}


Solution 1:[1]

The problem looks you missed RoutedEventHandler parameter for Click method. In general, I don't recommend declare click routed event handler in view model, because it will pass current button instance into view model that make view and viewmodel are highly coupled.

You could bind AppBarButton Command property. please research C++/WinRT XAML command handling tutorial.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1