Binding UI control to a property from another ViewModel

I’m writing an app in C# using WinUI 3 platform.
Being new to this world, my starting point is the template created through Template Studio.
I’m also using MVVM Community Toolkit.

I’m planning to use the blank space in the left Navigation Pane to add context-based UI controls.
So, for example, if the user is in page SimpRec and clicks a button, a section appears on the left navigation pane with 2 ComboBoxes used to filter some data.

The Navigation Pane is defined in my ShellPage.xaml as follows and its Visibility property is to be bound to property IsFilterMenuVisible.

ShellPage.xaml:

<Page>
<!--Other code-->
<NavigationViewItemHeader Content="Simp Rec" />

<NavigationViewItem Icon="Filter"
                    Content="Filters"
                    SelectsOnInvoked="False"
                    IsSelected="False"
                    Visibility="{x:Bind IsFilterMenuVisible, Mode=OneWay}"
                    AutomationProperties.Name="filter">
    <NavigationViewItem.MenuItems>
        <StackPanel Orientation="Horizontal">
            <FontIcon FontFamily="{StaticResource FabExIcons}"
                      Glyph=""
                      Margin="{StaticResource SmallRightMargin}" />
            <ComboBox Text="Filter by Period"
                      Width="200"
                      ToolTipService.ToolTip="Periods" />
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <FontIcon FontFamily="{StaticResource CustomIconFont}"
                      Glyph=""
                      Margin="{StaticResource SmallRightMargin}" />
            <ComboBox Text="Filter by Model"
                      Width="200"
                      ToolTipService.ToolTip="Models" />
        </StackPanel>
    </NavigationViewItem.MenuItems>
</NavigationViewItem>

<!--More code-->

</Page>

I did some research and to reach my goal I decided to create the [ObservableProperty] in my SimpRecViewModel as highlighted in the following code where the [RelayCOmmand] to be used to updated the status of property IsFilterMenuVisible is also shown.:

SimpRecViewModel.cs:

public partial class SimpRecViewModel : ObservableRecipient, INavigationAware
{
    private readonly INavigationService _navigationService;
    private readonly IAppService _appDiagnosticsService;

    [ObservableProperty]
    private Visibility isFilterMenuVisible = Visibility.Collapsed;

    public SimpRecViewModel(INavigationService navigationService, IAppService appDiagnosticsService)
    {
        _navigationService = navigationService;
        _appDiagnosticsService = appDiagnosticsService;
    }

    public async void OnNavigatedTo(object parameter)
    {
        // Some code
    }

    public void OnNavigatedFrom()
    {
    }

    [RelayCommand]
    private async Task ShowFilters(int selectedIndex)
    {
        // Some code

        IsFilterMenuVisible = Visibility.Visible;

        // More code
    }

I added a SimpRecViewModel as a parameter in the constructor of ShellViewModel:

ShellPage.xaml.cs:

public sealed partial class ShellPage : Page
{
    public ShellViewModel ViewModel
    {
        get;
    }

    public SimpRecViewModel SRViewModel
    {
        get;
    }

    public ShellPage(ShellViewModel viewModel, SimpRecViewModel srViewModel)
    {
        ViewModel = viewModel;
        InitializeComponent();
        SRViewModel = srViewModel;
        ViewModel.NavigationService.Frame = NavigationFrame;
        ViewModel.NavigationViewService.Initialize(NavigationViewControl);

        // More code
}

And I updated the DataContext of the NavigationViewItem to the SRViewModel:

ShellPage.xaml:

<Page 
      xmlns:srvm="using:MyApp.ViewModels">

<!--Some code-->

<NavigationViewItem Icon="Filter"
                    Content="Filters"
                    SelectsOnInvoked="False"
                    IsSelected="False"
                    Visibility="{x:Bind SRViewModel.IsFilterMenuVisible, Mode=OneWay}"
                    AutomationProperties.Name="filter">
    <NavigationViewItem.DataContext>
        <srvm:SimpRecViewModel />
    </NavigationViewItem.DataContext>

<!--More code-->

</Page>

And I had to add a parameterless constructor to my SimpRecViewModel to avoid error XLS0507.

When I tried the code, the filter section in the left pane was correctly collapsed, but when I hit the button, nothing changed. I expected to see the section appear instead.

Another approach I tried based on an answer to a similar question (/questions/16506653/accessing-a-property-in-one-viewmodel-from-another) was to create the [ObservableProperty] IsFilterMenuVisible in the ShellViewModel as follows:

ShellViewModel.cs:

public partial class ShellViewModel : ObservableRecipient
{
    // Some code

    [ObservableProperty]
    private Visibility isFilterMenuVisible = Visibility.Collapsed;

    public INavigationService NavigationService
    {
        get;
    }

    public INavigationViewService NavigationViewService
    {
        get;
    }

    public ShellViewModel(INavigationService navigationService, INavigationViewService navigationViewService)
    {
        NavigationService = navigationService;
        NavigationService.Navigated += OnNavigated;
        NavigationViewService = navigationViewService;
    }

    private void OnNavigated(object sender, NavigationEventArgs e)
    {
        IsBackEnabled = NavigationService.CanGoBack;

        if (e.SourcePageType == typeof(SettingsPage))
        {
            Selected = NavigationViewService.SettingsItem;
            return;
        }

        // More code
    }
}

And to modify the SimpRecViewModel to add ShellViewModel as a parameter in the constructor:

SimpRecViewModel.cs:

public partial class SimpRecViewModel : ObservableRecipient, INavigationAware
{
    private readonly INavigationService _navigationService;
    private readonly IAppService _appDiagnosticsService;

    // Some code

    public ShellViewModel ShellViewModel { get; set; }

    public SimpRecViewModel(INavigationService navigationService, IAppService appDiagnosticsService, ShellViewModel shellViewModel)
    {
        _navigationService = navigationService;
        _appDiagnosticsService = appDiagnosticsService;
        ShellViewModel = shellViewModel;
    }

    public async void OnNavigatedTo(object parameter)
    {
        // Other code
    }

    public void OnNavigatedFrom()
    {
    }

    [RelayCommand]
    private async Task ShowFilters(int selectedIndex)
    {
        // Some code
        ShellViewModel.IsFilterMenuVisible = Visibility.Visible;

        // More code
        
}

Pressing the button had no effect on the Visibility of the Filter section in the Navigation Pane.

As a check, I added the option of changing the Visibility as a result of the selection of Settings Page within the ShellViewModel.

ShellViewModel.cs:

public partial class ShellViewModel : ObservableRecipient
{
    // Some code as before

    [ObservableProperty]
    private Visibility isFilterMenuVisible = Visibility.Collapsed;

    // Same code too

    private void OnNavigated(object sender, NavigationEventArgs e)
    {
        IsBackEnabled = NavigationService.CanGoBack;

        if (e.SourcePageType == typeof(SettingsPage))
        {
            Selected = NavigationViewService.SettingsItem;
            IsFilterMenuVisible = Visibility.Visible;
            return;
        }

        // Same code shown previously
    }
}

This time, clicking on the Settings icon had indeed the effect of making the Filter section visible.

The linked answer also proposed to create a static instance of ShellViewModel (in my case) and access it from SimpRecViewModel.

I tried this approach by first creating a parameterless constructor for ShellViewModel.
The reason being that I don’t know what parameters to pass to

private static ShellViewModel _instance = new ShellViewModel();

if the constructor has the following signature:

public ShellViewModel(INavigationService navigationService, INavigationViewService navigationViewService)

ShellViewModel.cs:

public partial class ShellViewModel : ObservableRecipient
{
    // Usual code

    [ObservableProperty]
    private Visibility isFilterMenuVisible = Visibility.Collapsed;


    private static ShellViewModel _instance = new ShellViewModel();
    public static ShellViewModel Instance { get { return _instance; } }

    ShellViewModel() { }

    public INavigationService NavigationService
    {
        get;
    }

    public INavigationViewService NavigationViewService
    {
        get;
    }

    public ShellViewModel(INavigationService navigationService, INavigationViewService navigationViewService)
    {
        NavigationService = navigationService;
        NavigationService.Navigated += OnNavigated;
        NavigationViewService = navigationViewService;
    }

    // All the other code
}

Then I used the static instance of ShellViewModel to change the status of the property IsFilterMenuVisible. With no effect.

SimpRecViewModel.cs:

public partial class SimpRecViewModel : ObservableRecipient, INavigationAware
{
    // Previous code

    public SimpRecViewModel(INavigationService navigationService, IAppService appDiagnosticsService)
    {
        _navigationService = navigationService;
        _appDiagnosticsService = appDiagnosticsService;
    }

    // Unrelated code

    [RelayCommand]
    private async Task ShowFilters(int selectedIndex) // async Task ShowFilters(int selectedIndex)
    {
        // Other code

        ShellViewModel.Instance.IsFilterMenuVisible = Visibility.Visible;

        // Final code
}

Which means that I’m clearly failing to understand how to properly set the DataContext of that section of the Navigation Pane to a different ViewModel.

My ideal scenario is one in which the DataContext is set to the SRViewModel page. That is because I’m planning to have other properties from that page to affect some controls of the UI in ShellPage.xaml.
And other pages are going to have similar impacts on ShellPage.xaml.

Any help is appreciated.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật