How to update ItemSource of ContextMenu with using MVVM

186 views Asked by At

I have a ContextMenu and I am trying to bind a list from my ViewModel class. I set this List with using two different Methods. OnZonesReceived method is triggered when changes are made and OnItemReceivedmethod is triggered when selected tab item changed. In this project I have tabItems and each tabItem has its own DesignerCanvas.

The problem is Zones is updated when selected tab Item changed but it is not updated when DesignerCanvas updated while OnZonesReceived method is triggered and The input "canvas" has the correct Zones List.

ResouceDictionary

<MenuItem Header="Zones" ItemsSource="{Binding Zones, Mode=TwoWay}">
            <MenuItem.DataContext>
                <viewModel:ZoneViewModel/>
            </MenuItem.DataContext>
            <MenuItem.ItemTemplate>
                <DataTemplate DataType="{x:Type dataModel:ZoneModel}" >
                    <TextBlock Text="{Binding Name}"/>
                </DataTemplate>
            </MenuItem.ItemTemplate>
        </MenuItem>

ViewModel

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using Core.Media;
using PropulsimGUI.Controls;
using PropulsimGUI.DataModel;
using PropulsimGUI.Utilities;

namespace PropulsimGUI.ViewModel
{
    public class ZoneViewModel : INotifyPropertyChanged
    {
        public ZoneViewModel()
        {
            Messenger.Default.Register<ClosableTab>(this, OnItemReceived);
            Messenger.Default.Register<DesignerCanvas>(this, OnZonesReceived, "Zone");
        }

        private void OnZonesReceived(DesignerCanvas canvas)
        {
            Zones = canvas.Zones;
        }

        public void OnItemReceived(ClosableTab item)
        {
            Zones = item.DesignerCanvas.Zones;
        }

        private List<ZoneModel> _zones;

        public List<ZoneModel> Zones
        {
            get { return _zones; }

            set
            {
                _zones = value;
                RaisePropertyChanged("Zones");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public void RaisePropertyChanged(string propertyThatChanged)
        {
            //checking if event is not null than raise event and pass
            //in propperty name that has changed
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyThatChanged));
        }
    }
}
1

There are 1 answers

0
Rekshino On

You give not enough information, but as I can see, if event OnZonesReceived is called and code Zones = item.DesignerCanvas.Zones; works, then the only reason why Zones = canvas.Zones; doesn't work is that canvas.Zones is the same object, in this case despite RaisePropertyChanged("Zones"); binding to Zones will not be updated. I.e. code

Zones.Add(new ZoneModel());
Zones=Zones;

will NOT update the ItemsSource.

You solution can be:

private void OnZonesReceived(DesignerCanvas canvas)
{
    Zones = new List<ZoneModel>(canvas.Zones);
}