This is a migrated thread and some comments may be shown as answers.

One menu item needs to change the state (enabled/disabled) of some other items in the menu.

2 Answers 408 Views
Menu
This is a migrated thread and some comments may be shown as answers.
Mart71
Top achievements
Rank 1
Mart71 asked on 21 Jan 2014, 01:02 AM
Hello,

I'm using RadMenu in a "C#-WPF-MVVM-Microsoft Prism" application.

I have made a very simple example that reproduces the problem. In this example, I have a "File" menu with two items: "Open" and "Close".
At first, I want the "Open" item to be enabled, and the "Close" item to be disabled since there is nothing to close.

When the user clicks on "Open", the open operation is called via a Prism DelegateCommand. 
After this, I want the "Open" item to be disabled and the "Close" item to be enabled.

If you run the example, you will see that now both items are disabled.

MainWindow.xaml:
<Window x:Class="WpfApplication1.MainWindow"
        xmlns:Effects="clr-namespace:Telerik.Windows.Controls.ColorEditor.Effects;assembly=Telerik.Windows.Controls.Input"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
   <Window.Resources>
      <Style x:Key="MenuStyle" TargetType="telerik:RadMenuItem">
         <Setter Property="Header" Value="{Binding Name}"/>
         <Setter Property="ItemsSource" Value="{Binding ItemsCollection}"/>
         <Setter Property="Command" Value="{Binding MenuItemCommand}"/>
      </Style>
   </Window.Resources>
    <
Grid>
      <telerik:RadMenu x:Name="radMenu" ItemsSource="{Binding MenusCollection}" ItemContainerStyle="{StaticResource MenuStyle}" HorizontalAlignment="Left" VerticalAlignment="Top">
      </telerik:RadMenu>
   </Grid>
</Window>


MainWindow.xaml.ca:
namespace WpfApplication1
   {
   /// <summary>
   /// Interaction logic for MainWindow.xaml
   /// </summary>
   public partial class MainWindow : Window
      {
      ViewModel _viewModel = new ViewModel();
      public MainWindow()
         {
         InitializeComponent();
         base.DataContext = _viewModel;
         }
      }
   }


ViewModel.cs :
using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Practices.Prism.Events;
using Microsoft.Practices.Prism.ViewModel;
using Microsoft.Practices.Prism.Commands;
 
namespace WpfApplication1
   {
   public delegate void MenuActionDelegate(object command);
   public delegate bool MenuIsEnabledDelegate(object command);
 
   public class ViewModel : NotificationObject
      {
      public ViewModel()
         {
         _menusCollection = new ObservableCollection<MyMenuItem>();
 
         MyMenuItemInfo menuInfo = new MyMenuItemInfo("File", 1, null, null);
         MyMenuItemInfo itemInfo = new MyMenuItemInfo("Open", 10, MenuAction, IsClosed);
         AddMenu(menuInfo, itemInfo);
 
         itemInfo = new MyMenuItemInfo("Close", 20, MenuAction, IsOpened);
         AddMenu(menuInfo, itemInfo);
         }
 
      private bool _isOpen;
      public bool IsOpened(object command)
         {
         return _isOpen;
         }
      public bool IsClosed(object command)
         {
         return !_isOpen;
         }
 
      public void MenuAction(object command)
         {
         if ((int)command == 10)
            {
            _isOpen = true;
            }
         else if ((int)command == 20)
            {
            _isOpen = false;
            }
         }
 
      private ObservableCollection<MyMenuItem> _menusCollection { get; set; }
      public ObservableCollection<MyMenuItem> MenusCollection
         {
         get { return this._menusCollection; }
         }
 
      public void AddMenu(MyMenuItemInfo menuInfo, MyMenuItemInfo itemInfo)
         {
         bool menuExists = false;
         MyMenuItem theMenu = null;
         foreach (MyMenuItem menu in _menusCollection)
            {
            if (menu.Name == menuInfo.Name)
               {
               theMenu = menu;
               menuExists = true;
               }
            }
 
         if (menuExists)
            {
            theMenu.AddMenuItem(itemInfo);
            }
         else
            {
            MyMenuItem newMenu = new MyMenuItem(menuInfo);
            newMenu.AddMenuItem(itemInfo);
            _menusCollection.Add(newMenu);
            }
         }
      }
 
 
   public class MyMenuItem
      {
      public MyMenuItem(MyMenuItemInfo itemInfo)
         {
         _itemInfo = itemInfo;
         _menuItemsCollection = new ObservableCollection<MyMenuItem>();
         MenuItemCommand = new DelegateCommand(MenuItemExecute, MenuItemCanExecute);
         }
 
      public void AddMenuItem(MyMenuItemInfo itemInfo)
         {
         MyMenuItem menuItem = new MyMenuItem(itemInfo);
         _menuItemsCollection.Add(menuItem);
         }
 
      private ObservableCollection<MyMenuItem> _menuItemsCollection { get; set; }
      public ObservableCollection<MyMenuItem> ItemsCollection
         {
         get { return _menuItemsCollection; }
         }
 
      public DelegateCommand MenuItemCommand { get; private set; }
 
      public void MenuItemExecute()
         {
         if (_itemInfo.MenuAction != null)
            {
            _itemInfo.MenuAction.Invoke(_itemInfo.Command);
            MenuItemCommand.RaiseCanExecuteChanged();
            }
         }
 
      private bool MenuItemCanExecute()
         {
         bool itemIsEnabled = true;
         if (_itemInfo.IsEnabled != null)
            {
            itemIsEnabled = _itemInfo.IsEnabled.Invoke(_itemInfo.Command);
            }
         return itemIsEnabled;
         }
 
      private MyMenuItemInfo _itemInfo;
      public string Name
         {
         get { return _itemInfo.Name; }
         set { _itemInfo.Name = value; }
         }
      }
 
 
 
   public class MyMenuItemInfo
      {
      public MyMenuItemInfo(string name, object command, MenuActionDelegate menuAction, MenuIsEnabledDelegate isEnabled)
         {
         Name = name;
         Command = command;
         MenuAction = menuAction;
         IsEnabled = isEnabled;
         }
 
      public string Name
         {
         get { return _name; }
         set { _name = value; }
         }
      public object Command
         {
         get { return _command; }
         set { _command = value; }
         }
      public MenuActionDelegate MenuAction
         {
         get { return _menuAction; }
         set { _menuAction = value; }
         }
      public MenuIsEnabledDelegate IsEnabled
         {
         get { return _isEnabled; }
         set { _isEnabled = value; }
         }
 
      private string _name;
      private object _command;
      private MenuActionDelegate _menuAction;
      private MenuIsEnabledDelegate _isEnabled;
      }
   }



Did I missed something?

Thanks
Mart71

2 Answers, 1 is accepted

Sort by
0
Accepted
Kalin
Telerik team
answered on 23 Jan 2014, 03:24 PM
Hello Mart,

You can achieve the desired scenario by enabling/disabling the MenuItems or the Commands themselves. For the first approach you will need to have a bool property bound the IsEnabled property in MenuItemStyle in XAML. For the second approach you will need to change the CanExecute value of the commands attached to the custom MenuItems when the command is executed. I have prepared and attached a sample project which demonstrates the second approach.

Hope this helps.

Regards,
Kalin
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Mart71
Top achievements
Rank 1
answered on 25 Jan 2014, 01:03 AM
Hello Kalin,

I have implemented something similar a few days ago. I was worried about performances, because my application contains a menus hierarchy with many menu items. Finally, it seems to be OK.

Yout answer give me the confirmation that this is the good approach.
Thanks,
Mart
Tags
Menu
Asked by
Mart71
Top achievements
Rank 1
Answers by
Kalin
Telerik team
Mart71
Top achievements
Rank 1
Share this question
or