How can a sub menuitem click call an action on the view's viewmodel?

Topics: Actions & Coroutines
Jul 1, 2012 at 2:13 AM
Edited Jul 1, 2012 at 2:15 AM

I have a top level menu in my ShellView and when selecting a sub MenuItem, I would like to call the following method on the ShellViewModel.

        public void SelectServer(string pServerName)
        {
            mDefaultClaimServer = pServerName;
        }

The following does not work as no method gets called (I have tried various signatures and action parameters) -

        <Menu Name="menu1" DockPanel.Dock="Top">
            <MenuItem Header="Select Server" Name="mSelectServer" ItemsSource="{Binding ClaimServers}">
                <MenuItem.ItemTemplate>
                    <DataTemplate>
                        <!-- we need this else we show the class name -->
                        <TextBlock Text="{Binding DisplayName}">
                            <ContentControl cal:Message.Attach="[Event Click] = [Action TxTester.ShellViewModel.SelectServer($Text)]"/>
                        </TextBlock>
                    </DataTemplate>
                </MenuItem.ItemTemplate>
            </MenuItem>
        </Menu>

The following does call the ShellViewModel SelectServer method but I get null for the text of the clicked sub MenuItem (I also tried various signatures and action parameters) -

        <Menu Name="menu1" DockPanel.Dock="Top">
            <MenuItem Header="Select Server" Name="mSelectServer" ItemsSource="{Binding ClaimServers}" cal:Message.Attach="SelectServer($this.Text)">
                <MenuItem.ItemTemplate>
                    <DataTemplate>
                        <!-- we need this else we show the class name -->
                        <TextBlock Text="{Binding DisplayName}" />
                    </DataTemplate>
                </MenuItem.ItemTemplate>
            </MenuItem>
        </Menu>

I've been struggling with this a long time and can't figure it out. Can someone suggest the proper combination where I can pass the header text of a sub MenuItem to the ShellViewModel?

Thanks so much, Dave

Jul 1, 2012 at 10:07 PM
Edited Jul 1, 2012 at 10:09 PM

I got what I was trying to do working, per a post from Rob Eisenberg describing a "special trick to get the text from bound submenus" here - http://caliburnmicro.codeplex.com/discussions/287228

I would still love to know how to do what I was trying to do with standard OOTB logic if anyone has suggestions, so that I am able to understand CM better.

Basically I added this to the bootstrapper Configure() overide -

            MessageBinder.SpecialValues.Add("$originalsourcecontext", context =>
            {
                var args = context.EventArgs as RoutedEventArgs;
                if (args == null)
                    return null;

                var fe = args.OriginalSource as FrameworkElement;
                if (fe == null)
                    return null;

                return fe.DataContext;
            });

and added this to the xaml -

            <MenuItem Header="_Select Server" Name="ClaimServers" cal:Message.Attach="SelectServer($originalsourcecontext)" />

and then I was passed the header text of the sub menuitem which is what I wanted.