0

On the base of this sample, I'd like to Add, Remove items from Menu programmatically, for example in this way:

    void ChangeItemSubitems()
    {
        // TODO: Add event handler implementation here.
        MenuItems.Add(new MenuItemViewModel { Header = "delta" });
        MenuItems[3].MenuItems = new ObservableCollection<MenuItemViewModel>();
        MenuItems[3].MenuItems.Add(new MenuItemViewModel { Header = "delta 1" });
        MenuItems[3].MenuItems.Add(new MenuItemViewModel { Header = "delta 2" });
        MenuItems.Remove(MenuItems[1].MenuItems[0]);
    }

Only the Add of Items at high level works fine, not submenu, neither the Remove. What is it wrong? Could you give me some hints? Thanks

EDIT: change made to MenuItemViewModel

    public class MenuItemViewModel : ViewModelBase 
{
    private readonly ICommand _command;

    public MenuItemViewModel()
    {
        _command = new CommandViewModel(Execute);
    }

    public MenuItemViewModel(Action action)
    {
        _command = new CommandViewModel(action);
    }

    private string _header;

    public string Header 
    { 
      get { return _header;  }
      set
      {
            _header = value;
            RaisePropertyChangedEvent("Header");
      }
    }

    public ObservableCollection<MenuItemViewModel> MenuItems { get; set; }

    public ICommand Command
    {
        get
        {
            return _command;
        }
    }

    private void Execute()
    {
        // (NOTE: In a view model, you normally should not use MessageBox.Show()).
        MessageBox.Show("Clicked at " + Header);
    }
}

public class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChangedEvent(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChangedEventArgs e = new PropertyChangedEventArgs(propertyName);
            PropertyChanged(this, e);
        }
    }
}
Community
  • 1
  • 1
G.Zana
  • 11
  • 7
  • 1
    What is your XAML? Do you utilize `HierarchicalDataTemplate`? Do you implement `INotifyPropertyChanged` for the `MenuItems` property? – grek40 Nov 15 '16 at 09:38
  • @grek40, the XAML is quite the same of original ...not so different yet. Yes, I've implemented INotifyPropertyChanged, but seems it works fine (updating the item itself), only if we modify the original tree. – G.Zana Nov 15 '16 at 10:35

1 Answers1

0

Your problem is most probably with

public ObservableCollection<MenuItemViewModel> MenuItems { get; set; }

While ObservableCollection will notify the UI when there are item changes, your MenuItemViewModel still needs to notify when the collection itself changes. So try

private ObservableCollection<MenuItemViewModel> _menuItems;
public ObservableCollection<MenuItemViewModel> MenuItems
{
    get
    {
        return _menuItems;
    }
    set
    {
        _menuItems = value;
        RaisePropertyChangedEvent("MenuItems");
    }
}

Edit. The remove statement has a different problem:

MenuItems.Remove(MenuItems[1].MenuItems[0]);

This tries to remove the inner submenu-item from an outer collection. However, MenuItems[1].MenuItems[0] is not an element of MenuItems to begin with, so Remove should return false in this case and WPF is certainly not at fault for not changing the view.

Try the following instead:

MenuItems[1].MenuItems.Remove(MenuItems[1].MenuItems[0]);

It should find and remove the specified item.

grek40
  • 13,113
  • 1
  • 24
  • 50
  • Thanks @grek40, sorry I was not clear. There is no problem to _Add_ and even _Remove_ menu Items, to the original tree, they were updated. No problem too if I change the _Header_ of original Items, menu or submenu. It doesn't work if I try to add new submenu... – G.Zana Nov 15 '16 at 11:20
  • @G.Zana So, did you implement my suggestion and it is not working? because things like `MenuItems[3].MenuItems = new ObservableCollection();` should behave different, when the property change is correctly notified. – grek40 Nov 15 '16 at 11:28
  • ...it doesn't work if I try to remove existing submenus. – G.Zana Nov 15 '16 at 11:33
  • @G.Zana Ok, `Remove` had a different problem. Updated answer. – grek40 Nov 15 '16 at 11:39
  • no, actually I haven't implemented your suggestion, seems like _Menu_ items are already notified.. – G.Zana Nov 15 '16 at 11:39
  • @G.Zana well then how about trying the rest of my answer? Its possible that I overlooked something different, but its very likely to solve at least part of your problem. – grek40 Nov 15 '16 at 11:48
  • now I think, my only problem still the insert of submenu...Do you really think is related to modify you suggest? ...why indeed I have no problem with add/remove of main header?...Thanks – G.Zana Nov 15 '16 at 12:01
  • @G.Zana wow... can you possibly imagine that I'm not very amused when you ask me, whether I really think that my answer applies? Do you think I write some useless random answers for fun? Is it HARD to copy paste 3 lines of code and just try if it works before re-asking things that I already addressed? Just suit yourself. – grek40 Nov 15 '16 at 12:04
  • Thanks @grek40. Okay, I have replaced the pieces of code, as you suggest. Nothing really happens when I try to _add_ a new Menu and some submenu as the first function posted above did. – G.Zana Nov 15 '16 at 12:42
  • @G.Zana I have a working example here, I clicked it together in seconds from the code you provided and my change suggestions. It is working in the sense of (1) initializing the menu (2) adding new menu items (3) adding new sub menus (4) removing menu items (potentially including their sub menus). So if its not working for you, then there is a fault somewhere in your code that you didn't include in the question. – grek40 Nov 15 '16 at 12:57
  • you alright! It works, sorry but I made the change you suggested on variable in the class _MainWindow_ not in class _MenuItemViewModel_. Now it works perfectly. Beg a pardon and thank you so much for your kindness – G.Zana Nov 15 '16 at 12:57
  • @G.Zana glad to hear that you got it working. Maybe the `INotifyPropertyChanged` part should be corrected in the question that [you originally referred to](http://stackoverflow.com/a/23941998/5265292). – grek40 Nov 16 '16 at 07:40