Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

XAML MenuItem w/ Custom CommandBinding Disabled ?

Status
Not open for further replies.

Nimroduk

Programmer
Aug 10, 2006
77
GB
Hi all,
I couldn't find a WPF / XAML forum so I am hoping that either someone here will have some ideas or point me in the direction of the right forum to use !

I have created my own RoutedUICommands that I am binding to MenuItems. The problem is that once the Command are bound to their MenuItems, the MenuItems becomes inactive. The strange thing is that the commands function ok if I use the InputGestureText that I have associated with the command, even through the MenuItems are disabled ??

I am attempting to do all of the binding work in XAML, with the Executed/CanExecute routines being in the Window's code behind. The only visable controls on the Window are the menu and an instance of the Xceed GridControl.

Here is my code:
RoutedUICommand Implementations:
Code:
    public static class frmMainCommands {
        //Provides thread locking (code pattern !)
        private static object syncRoot = new object();

        //FrmMain Commands
        private static RoutedUICommand cmdExit = null;
        private static RoutedUICommand cmdRefresh = null;

        public static RoutedUICommand Exit {
            get {
                //Make sure we don't accidently create multiple instances of the command
                lock (syncRoot) {
                    cmdExit = new RoutedUICommand("E_xit", "Exit", typeof(frmMainCommands));
                    cmdExit.InputGestures.Add(new KeyGesture(Key.Q, ModifierKeys.Control));
                }
                return cmdExit;
            }
        }
        public static RoutedUICommand Refresh {
            get {
                //Make sure we don't accidently create multiple instances of the command
                lock (syncRoot) {
                    cmdRefresh = new RoutedUICommand("_Refresh", "Refresh", typeof(frmMainCommands));
                    cmdRefresh.InputGestures.Add(new KeyGesture(Key.F5));
                }
                return cmdRefresh;
            }
        }
    }

XAML from frmMain.xaml :
Code:
<Window xmlns:local="clr-namespace:TLC.TLCAllocationsViewer" ... />

    <Window.CommandBindings>
        <CommandBinding Command="{x:Static local:frmMainCommands.Exit}" Executed="cmdFileExit" CanExecute="AlwaysExecuteCmd"/>
        <CommandBinding Command="{x:Static local:frmMainCommands.Refresh}" Executed="cmdRefresh" CanExecute="AlwaysExecuteCmd"/>
    </Window.CommandBindings>

<DockPanel>
        <Menu DockPanel.Dock="Top">
            <MenuItem Header="_File">
                <MenuItem Name="mnuFileExit" Header="E_xit" Command="{x:Static local:frmMainCommands.Exit}"></MenuItem>
            </MenuItem>
            <MenuItem Header="_View">
                <MenuItem Name="mnuViewRefresh" Header="_Refresh" Command="{x:Static local:frmMainCommands.Refresh}"></MenuItem>
            </MenuItem>
        </Menu>

        ...</DockPanel>
...</Window>

Code Behind frmMain.xaml.cs:
Code:
        private void cmdRefresh(object sender, ExecutedRoutedEventArgs e) {
            grdAllocations.Columns.Clear();
            dataFilters = null;
            noAllocations.LoadAllocations();
        }

        private void cmdFileExit(object sender, ExecutedRoutedEventArgs e) {
            Application thisApp = (App)App.Current;
            thisApp.Shutdown();
        }

        private void AlwaysExecuteCmd(object sender, CanExecuteRoutedEventArgs e) {
            e.CanExecute = true;
        }

By putting a breakpoint in AlwaysExecuteCmd I can see that the routine is only ever called if I hit CTRL+Q or F5 ?

I don't understand why I am having problems :s
I have tried setting the CommandTarget to the window but that appears to make no difference.

Any advice will be greatly appreciated.

 
Solved this !
It was painfully obvious but also annoyingly subtle.

The problem was in my static properties that returned the RoutedUICommands. The code was always creating a new instance of the RoutedUICommand, so the command referenced by the Window and the one referenced by the MenuItem were two different instances. *sigh*

Fixed code:
Code:
namespace TLC.TLCAllocationsViewer {
    /// <summary>
    /// Menu Command Logic for frmMain.xaml
    /// </summary>
    public static class frmMainCommands {
        //Provides thread locking (code pattern !)
        private static object syncRoot = new object();

        //FrmMain Commands
        private static RoutedUICommand cmdExit = null;
        private static RoutedUICommand cmdRefresh = null;

        public static RoutedUICommand Exit {
            get {
                //Make sure we don't accidently create multiple instances of the command
                if (cmdExit == null) {
                    lock (syncRoot) {
                        cmdExit = new RoutedUICommand("E_xit", "Exit", typeof(frmMainCommands));
                        cmdExit.InputGestures.Add(new KeyGesture(Key.Q, ModifierKeys.Control));
                    }
                }
                return cmdExit;
            }
        }
        public static RoutedUICommand Refresh {
            get {
                //Make sure we don't accidently create multiple instances of the command
                if (cmdRefresh == null) {
                    lock (syncRoot) {
                        cmdRefresh = new RoutedUICommand("_Refresh", "Refresh", typeof(frmMainCommands));
                        cmdRefresh.InputGestures.Add(new KeyGesture(Key.F5));
                    }
                }
                return cmdRefresh;
            }
        }
    }
}
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top