Enable or disable context menu from vb.net code - wpf

I have following context menu which should only be enabled if my "Globals.admin = true".
I have other context menus bound specificaly for some button, label, control, etc. My idea is to enable/disable this context menu bellow based on state of "Globals.admin" in my vb.net code
<ContextMenu x:Key="cm">
<MenuItem Header="Block" Click="MenuItem_Click" />
<MenuItem Header="Unblock" Click="MenuItem2_Click"/>
<MenuItem Header="-"/>
<MenuItem Header="Hide="MenuItem3_Click"/>
<MenuItem Header="Show="MenuItem4_Click"/>
</ContextMenu>

Bind the IsEnabled property to your static source property:
<ContextMenu x:Key="cm" IsEnabled="{Binding Source={x:Static local:Globals.admin}}">
<MenuItem Header="Block" Click="MenuItem_Click" />
<MenuItem Header="Unblock" Click="MenuItem2_Click"/>
<MenuItem Header="-"/>
<MenuItem Header="Hide" />
<MenuItem Header="Show" />
</ContextMenu>

Related

How can I take different MenuItem controls and use them in one ContextMenu?

For example, I have a simple control below in xaml:
<ContextMenu>
<MenuItem Header = "Open in new tab"/>
<MenuItem Header = "Open in new window"/>
<MenuItem Header = "Open in incognito window"/>
<Separator Padding="0"/>
<MenuItem Header = "Edit..."/>
<Separator Padding="0"/>
<MenuItem Header = "Cut"/>
<MenuItem Header = "Copy"/>
<MenuItem Header = "Paste"/>
<Separator Padding="0"/>
<MenuItem Header = "Delete"/>
</ContextMenu>
Which produces:
I want the Cut/Copy/Paste MenuItem elements to sit in their own control. However, Wpf restricts me from just declaring 3 MenuItems in a control without a parent element. So I tried putting the MenuItems in a Menu, Grid, ItemsControl, and other controls with no luck. The formatting was weird. All i want to do is abstract the Cut/Copy/Paste into a seperate control, and have the end product look identical to the xaml above. Here were my failed attempts:
MyContextMenu.xaml:
<ContextMenu>
<MenuItem Header = "Open in new tab"/>
<MenuItem Header = "Open in new window"/>
<MenuItem Header = "Open in incognito window"/>
<Separator Padding="0"/>
<MenuItem Header = "Edit..."/>
<Separator Padding="0"/>
<ref:MyCutCopyPaste/>
<Separator Padding="0"/>
<MenuItem Header = "Delete"/>
</ContextMenu>
MyCutCopyPaste.xaml:
<Grid>
<MenuItem Header = "Cut"/>
<MenuItem Header = "Copy"/>
<MenuItem Header = "Paste"/>
<Grid>
I can probably take my solution and play around with formatting, but there has to be an easy solution that I'm oblivious too. I know I can also declare each Menu Item (Cut, Copy, and Paste) into it's own xaml file. But I'd like to keep all three in one file, if possible.
You can define those MenuItems as resources and use it in the contextmenu. Refer the below code.
<StackPanel>
<StackPanel.Resources>
<MenuItem x:Key="Cut" Header="Cut" x:Shared="false"/>
<MenuItem x:Key="Copy" Header="Copy" x:Shared="false"/>
<MenuItem x:Key="Paste" Header="Paste" x:Shared="false"/>
</StackPanel.Resources>
<Button Content="Button 1">
<Button.ContextMenu>
<ContextMenu>
<StaticResourceExtension ResourceKey="Cut"/>
<StaticResourceExtension ResourceKey="Copy"/>
<StaticResourceExtension ResourceKey="Paste"/>
<MenuItem Header="Open in new tab"/>
</ContextMenu>
</Button.ContextMenu>
</Button>
<Button Content="Button 2">
<Button.ContextMenu>
<ContextMenu>
<StaticResourceExtension ResourceKey="Cut"/>
<StaticResourceExtension ResourceKey="Copy"/>
<StaticResourceExtension ResourceKey="Paste"/>
<MenuItem Header="Open in new window"/>
</ContextMenu>
</Button.ContextMenu>
</Button>
</StackPanel>

How to apply a custom style context menu for TextBox (default context menu copy/cut/paste)?

I create style for the MenuItem.
When I create my own menu, everything is good.
But how can I apply a style to the context menu of TextBox?
I mean, the menu (Copy, Cut, Paste, etc.) - I do not want to create new lines, and just change the style.
//My Custom Menu Example
<UserControl.ContextMenu>
<ContextMenu Style="{StaticResource ContextMenuStyle}" HasDropShadow="True">
<MenuItem x:Name="MenuItem1" Header="Open"
Style="{StaticResource ContextMenuItem}">
</MenuItem>
<MenuItem x:Name="MenuItem2" Header="Save"
Style="{StaticResource ContextMenuItem}">
</MenuItem>
<MenuItem x:Name="MenuItem3" Header="Delete"
Style="{StaticResource ContextMenuItem}">
</MenuItem>
</ContextMenu>
</UserControl.ContextMenu>
You will technically have to to do the same thing you did to your UserControl.ContextMenu to the TextBox.ContextMenu.
Look the below link which has exactly the scenario you are asking about with xaml.

WPF menu tab navigation

I have a view with a menu:
<Menu IsTabStop="False">
<MenuItem
Header="_File"
IsTabStop="True">
<MenuItem
Header="New / Start Over"
IsTabStop="True"
InputGestureText="Ctrl+N"
Command="{x:Static common:Commands.StartOverCommand}" />
<Separator
IsTabStop="False" />
<MenuItem
Header="Log Out"
IsTabStop="True"
InputGestureText="F12"
Click="LogoutMenuItem_Click" />
<MenuItem
Header="E_xit"
IsTabStop="True"
InputGestureText="Alt+F4"
Click="ExitMenuItem_Click" />
</MenuItem>
<MenuItem
Header="_Edit"
IsTabStop="True">
<MenuItem
Header="Undo Edit Field"
IsTabStop="True"
InputGestureText="Ctrl+Z"
Click="_undoMenuItem_Click" />
<MenuItem
Header="Redo Edit Field"
IsTabStop="True"
InputGestureText="Ctrl+Y"
Click="_redoMenuItem_Click" />
</MenuItem>
<MenuItem
Header="_Tools"
IsTabStop="True">
<MenuItem
Header="Comments"
IsTabStop="True"
InputGestureText="Ctrl+M"
Click="_commentsMenuItem_Click" />
</MenuItem>
</Menu>
I would like to be able to navigate through the menus (File, Edit, Tools) by using the right and left arrow keys, which I was able to accomplish by making these MenuItems IsTabStop="True". But since I did this I am able to tab to the menu as I cycle through the other valid fields on a page. When I use Alt+F to put focus on the File menu I want to be able to cycle through the 3 menus with the arrow keys, but I don't want to be able to tab to these menus from the page. How would I accomplish this?
Use the KeyboardNavigation.TabNavigation Attached Property with KeyboardNavigationMode.None on menu.
<Menu KeyboardNavigation.TabNavigation="None">

XAML and Binding Submenu items in a ContextMenu?

I have a ContextMenu defined on a Datagrid but want to bind submenu items to a collection on my viewmodel. Can anybody suggest how this should be done?
The following is a simple example of what I'm trying to achieve, BUT I want "Test1", "Test2" to come from a collection on my viewmodel, not hardcoded. I know how to bind my collection to the whole ContextMenu, but not how to bind it to just the one submenu...
<ContextMenu>
<MenuItem Header="Add to">
<MenuItem Header="Test1" />
<MenuItem Header="Test2" />
</MenuItem>
<MenuItem Header="Remove from All" />
</ContextMenu>
I'm using 3.5 SP1 and the WPF Toolkit.
Guess I should have experimented more. Turns out this was relatively simple:
<my:DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Header="Add to" ItemsSource="{Binding MyItems}">
<MenuItem.ItemTemplate>
<DataTemplate>
<MenuItem CommandTarget="{Binding}" Click="AddClick">
<MenuItem.Header>
<TextBlock>
<TextBlock.Text><Binding StringFormat="Add to {0}" /></TextBlock.Text>
</TextBlock>
</MenuItem.Header>
</MenuItem>
</DataTemplate>
</MenuItem.ItemTemplate>
</MenuItem>
<MenuItem Header="Remove from All" />
</ContextMenu>
</my:DataGrid.ContextMenu>
There is a bug when using MenuItem.ItemTemplate. The color when do mouse over on the sub menu make user misunderstand that they can click to select the menu but it doesn't work for all area even if it's highlighted. See the picture
Then I used this code instead and it worked fine for me.
<ContextMenu>
<MenuItem Header="Add to" ItemsSource="{Binding MyItems}"
DisplayMemberPath="{Binding ItemName}">
<MenuItem.ItemContainerStyle>
<Style>
<EventSetter Event="MenuItem.Click" Handler="Menu_Click"/>
</Style>
</MenuItem.ItemContainerStyle>
</MenuItem>
<MenuItem Header="Remove from All" />
</ContextMenu>

How to add Submenus in a Menu

How does one make submenu's in WPF and are their ways to orientate the layout?
For submenus you can add as many MenuItem nested inside.
<Menu>
<MenuItem Header="File">
<MenuItem Header="Open"/>
<MenuItem Header="Close"/>
</MenuItem>
<MenuItem Header="Edit">
<MenuItem Header="Copy"/>
<MenuItem Header="Paste"/>
</MenuItem>
<MenuItem Header="Options"/>
Just redefine the ItemsPanel:
<Menu>
<Menu.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</Menu.ItemsPanel>
<MenuItem Header="Foo"/>
<MenuItem Header="Bar"/>
<MenuItem Header="Baz"/>
...
</Menu>
Note that this will not get rid of the vertical gradient effect in Vista/Win7 menus. If you want that, set Menu.Background property to whatever you want (could even be Transparent).

Resources