2

I have been trying to access the MasterMenuItem property after loading the details page, but I always get error that the MasterMenuItem is empty. What I am trying to do is after selecting an item in the MasterPage, I want to get the item's ID to load addresses from database. Here is my code:

ListView in my Details page I am trying to fill

<ListView x:Name="MainAddressListView"
          ItemsSource="{x:Bind MainAddressCollection}"/>

Code behind of my Details Page

public ObservableCollection<Address> MainAddressCollection { get; private set; } = new ObservableCollection<Address>(); 

public Client MasterMenuItem
{
    get { return GetValue(MasterMenuItemProperty) as Client; }
    set { SetValue(MasterMenuItemProperty, value); }
}

public ClientViewDetailControl()
{
    this.InitializeComponent();
    LoadAddresses();
}

private async void LoadAddresses()
{
    MainAddressCollection.Clear();

    var data = await AddressDataService.GetAddressesDataAsync();

    foreach (var address in data)
    {
        if (MasterMenuItem.Id == address.ClientId && address.ActiveStatus == 1) //This throws me an error that MasterMenuItem is null
        {
            if (address.IsPrimary)
                    MainAddressCollection.Add(address);
                else
                    OtherAddressesCollection.Add(address);
         }
    }
}

I have also tried to implement Loaded event for this with no luck. Weird thing is that everything else works just fine. When I try to fill addresses with a button for example, it works.

I could not find any information about it in the official documentation.

My question is in which event should I run the code to fill my address list or how should I approach this?

EDIT

Here is an inplementation of MasterMenuItemProperty:

public static readonly DependencyProperty MasterMenuItemProperty = DependencyProperty.Register("MasterMenuItem", typeof(Client), typeof(ClientViewDetailControl), new PropertyMetadata(null, OnMasterMenuItemPropertyChanged));

private static void OnMasterMenuItemPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var control = d as ClientViewDetailControl;
    control.ForegroundElement.ChangeView(0, 0, 1);
}

MasterMenuItem is passed on from MasterView to Details view as a whole object which I can use then as I please. Example of binding in XAML I have (and works as it should):

<TextBlock  Text="{x:Bind MasterMenuItem.ShortName, Mode=OneWay}"

For the record - I am using a template "MasterDetailsView" which is a part of the Windows Community Toolkit.

Cœur
  • 32,421
  • 21
  • 173
  • 232

1 Answers1

0

Ok, after some time and sleepless nights I finally came with the solution. The whole joke was in a definition of MasterMenuItem property and how it is being populated (which is kind of a tricky thing).

Basically, the first thing program is trying to do is to fill MasterMenuItem property (which is happening after selecting item in the MasterView), but it ends up being null. After that it goes through the code and several pages after which ends up again in the MasterMenuItem property - only now with an actual data about selected item. And since all events called in the DetailsView are triggered only after the first attempt to fill MasterMenuItem with some data, it never worked.

When I found out about that it was just a matter of editing the code in a way that it loads addresses right after it.

Original implementation of MasterMenuItem

public Client MasterMenuItem
    {
        get { return GetValue(MasterMenuItemProperty) as Client; }
        set { SetValue(MasterMenuItemProperty, value); }                
    }

Edited implementation of MasterMenuItem

public Client MasterMenuItem
    {
        get {
            Client Property = GetValue(MasterMenuItemProperty) as Client;
            if (Property != null)
                LoadAddresses(Property.Id);
            return Property as Client;
        }
        set { SetValue(MasterMenuItemProperty, value); }                
    }

Because this part of code is being called twice (first with Null value, second with selected Client), I had to implement if (Property != null) so it would only run when there are actually some data, but it works like a charm.

Thank you all for your help!