Child MenuItems are not expanding - c#

I have a simple popup control that holds multiple MenuItem's in it.
<Popup
IsOpen="{Binding ShowPopupMenu}"
<StackPanel Background="White">
<ItemsControl>
<MenuItem Header="Open file..." />
<MenuItem Header="Settings" />
<!-- Nested items -->
<MenuItem Header="Test">
<MenuItem Header="Nested Item" />
<MenuItem Header="Nested Item" />
<MenuItem Header="Nested Item" />
<MenuItem Header="Nested Item" />
<MenuItem Header="Nested Item" />
</MenuItem>
<MenuItem Header="Exit" />
</ItemsControl>
</StackPanel>
</Popup>
My problem is that MenuItem with header Test, that contains nested childrens is not expanding on mouse over.
I'm actually able to see it expanding in the design time
,
However, when it's simply not working on runtime.
Any ideas why is that?

It seems that the issue is that the Popup control handles mouse click event and, therefore, it does not reaches your menu item, try opening it manually by handling PreviewLeftButton event:
<StackPanel x:Name="Panel">
<Popup PlacementTarget="{Binding ElementName=Panel}"
IsOpen="True">
<StackPanel Background="White">
<!--<Menu>-->
<MenuItem Header="Open file..." />
<MenuItem Header="Settings" />
<!-- Nested items -->
<MenuItem Header="Test" Click="MenuItem_OnClick" PreviewMouseLeftButtonDown="UIElement_OnPreviewMouseLeftButtonDown">
<MenuItem Header="Nested Item" />
<MenuItem Header="Nested Item" />
<MenuItem Header="Nested Item" />
<MenuItem Header="Nested Item" />
<MenuItem Header="Nested Item" />
</MenuItem>
<MenuItem Header="Exit" />
<!--</Menu>-->
</StackPanel>
</Popup>
</StackPanel>
And:
private void UIElement_OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
((MenuItem)sender).IsSubmenuOpen = true;
}
EDIT
My mistake, the problem is not related with the Click event not being handled. I just put a button in the stackpanel and it worked. The problem is that when a MenuItem has subitems the click event is not fired and one must manually handled the state of the submenu if the root menu item is not "child" of either a Menu or a ContextMenu control. Those controls handle that already, but since you are implementing your own "ContextMenu" then you must implement that behavior by yourself

You could use a Style with a Trigger that sets the IsSubmenuOpen property to true:
<Popup IsOpen="True">
<StackPanel Background="White">
<ItemsControl>
<MenuItem Header="Open file..." />
<MenuItem Header="Settings" />
<!-- Nested items -->
<MenuItem Header="Test">
<MenuItem Header="Nested Item" />
<MenuItem Header="Nested Item" />
<MenuItem Header="Nested Item" />
<MenuItem Header="Nested Item" />
<MenuItem Header="Nested Item" />
<MenuItem.Style>
<Style TargetType="MenuItem">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="IsSubmenuOpen" Value="True" />
</Trigger>
</Style.Triggers>
</Style>
</MenuItem.Style>
</MenuItem>
<MenuItem Header="Exit" />
</ItemsControl>
</StackPanel>
</Popup>

Related

Avalonia .xaml can't go to definition, F12 also don't work, why?

<editor:DrawingNode.ContextFlyout>
<MenuFlyout>
<MenuItem Header="Cu_t" Command="{Binding CutCommand}" InputGesture="Ctrl+X" />
<MenuItem Header="_Copy" Command="{Binding CopyCommand}" InputGesture="Ctrl+C" />
<MenuItem Header="_Paste" Command="{Binding PasteCommand}" InputGesture="Ctrl+V" />
<MenuItem Header="_Delete" Command="{Binding DeleteCommand}" InputGesture="Delete" />
<MenuItem Header="-" />
<MenuItem Header="Select _All" Command="{Binding SelectAllCommand, FallbackValue={x:Null}}" InputGesture="Ctrl+A" />
<MenuItem Header="De_select All" Command="{Binding DeselectAllCommand, FallbackValue={x:Null}}" InputGesture="Escape" />
</MenuFlyout>
</editor:DrawingNode.ContextFlyout>
I want to go to the definition of cut command, but pressing F12 did not go to the definition/source of avalonia. Does avalonia support navigation to the definition of their elements in xaml?

WPF Disable MenuItem when the other MenuItem is Checked using IValueConverter

I tried to enable Item2 when Item1 is checked and disable it when Item1 is not checked. How to do that with IValueConverter to convert IsChecked property to Boolean and bind it to IsEnabled Property in Item2.
<ContextMenu x:Name="ItemsContxtMenu">
<MenuItem IsCheckable="True" x:Name="Item1" Header="item1 .."/>
<MenuItem x:Name="Item2" Header="item2 .." IsEnabled="{Binding ElementName=Item1, Path=IsChecked"}/>
</ContextMenu>
You don't need converter, write following xaml:
<Menu VerticalAlignment="Top">
<MenuItem Header="Items">
<MenuItem Name="item1" Header="Item #1" IsCheckable="True" />
<MenuItem Name="item2" Header="Item #2" IsEnabled="{Binding ElementName=item1,Path=IsChecked}" />
</MenuItem>
</Menu>

WPF, TreeViewItem, how to not show contextMenu according to dependency property?

I have a treeview using the following style:
<HierarchicalDataTemplate x:Key="itemTemplate" DataType="{x:Type AttCatalog:AttachmentCatalogModel}" ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Name}" Tag="{Binding Guid}">
<TextBlock.ContextMenu>
<ContextMenu>
<MenuItem Header="New Item"/>
<MenuItem Header="Move to..." />
<MenuItem Header="Delete" />
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</HierarchicalDataTemplate>
<TreeView x:Name="tree" HorizontalAlignment="Left" Width="216" BorderThickness="0,0,1,0" Background="#FFFBFBFB" IsEnabled="{Binding IsEnabled}" ItemsSource="{Binding Catalogs}" ItemTemplate="{StaticResource itemTemplate}" TreeViewItem.Expanded="OnExpandItemHandler" Margin="0,0,0,241" SelectedItemChanged="tree_SelectedItemChanged">
you can see TextBlock Tag binding a Guid property, my question is, how to do that when this Guid is empty (00000-00000000-00000), not show the contextMenu?
In your context menu, bind the visibility to the Guid, and treat it with a converter =>
<ContextMenu Visibility="{Binding Element=Guid,
Converter={StaticResource GuidToVisibilityConverter}}">
<MenuItem Header="New Item"/>
<MenuItem Header="Move to..." />
<MenuItem Header="Delete" />
</ContextMenu>
In your converter, you can treat your Guid value the way you want, to either return Visibility.Visible or Visibility.Hidden, depending on the value.
You can find more information on converters here.
Hope that helped !

How to Bind IsChecked Property of Menu item

Here My code to bind IsChecked property of menu.
<MenuItem Header="_View">
<MenuItem IsCheckable="True" IsChecked="{Binding ElementName=TermMenu, Path=IsChecked}" Header="Term" />
<MenuItem IsCheckable="True" IsChecked="True" Header="Key" />
<MenuItem IsCheckable="True" IsChecked="True" Header="Hand" />
<MenuItem IsCheckable="True" IsChecked="True" Header="Rule" />
</MenuItem>
Here is the context menu
<ContextMenu x:Key="DataGridColumnHeaderContextMenu" >
<MenuItem x:Name="TermMenu" IsCheckable="True" IsChecked="True" Header="Key Term" />
<MenuItem x:Name="Key" IsCheckable="True" IsChecked="True" Header="Key Term Description" />
<MenuItem x:Name="ShortHand" IsCheckable="True" IsChecked="True" Header="Hand" />
<MenuItem x:Name="Rule" IsCheckable="True" IsChecked="True" Header="Rule" />
</ContextMenu>
Now I want when the context menu item is check the main menu View will be checked automatically. But my code is not working. Please explain me why.
x:Name does not work in resources. the element with the specified name in ElementPath does not exist. this is why the binding doesn't work. you can't access TermMenu from the code behind either. You should bind both to a view-model as #wilford sugested.

How do I reuse item children via a style in XAML?

I have a WPF submenu that I want to reuse in a few places in my XAML. It's a collection of eight <MenuItem> elements with some complicated bindings that I don't want to copy/paste. However, the holder is different in each case: in one place the parent is a <Menu>, in another place the parent is a <MenuItem> in a <ContextMenu>.
I've been experimenting with <Setter Property="Items"> in my <Style> but I think maybe I'm on the wrong track.
To make it concrete, I'm trying to reduce the code duplication from something like this:
<Menu>
<MenuItem Header="Details" IsCheckable="True" ... />
<MenuItem Header="List" IsCheckable="True" ... />
<MenuItem Header="Thumbnails" IsCheckable="True" ... />
...
</Menu>
...
<ContextMenu>
<MenuItem Header="View">
<MenuItem Header="Details" IsCheckable="True" ... />
<MenuItem Header="List" IsCheckable="True" ... />
<MenuItem Header="Thumbnails" IsCheckable="True" ... />
...
</MenuItem>
</ContextMenu>
How about something like this:
You'll need to create the following collection in your resource dictionary:
<Collections:ArrayList x:Key="MenuItems" x:Shared="false">
<MenuItem Header="Details" />
<MenuItem Header="List" />
<MenuItem Header="Thumbnails" />
</Collections:ArrayList>
You'll need to add the following namespace:
xmlns:Collections="clr-namespace:System.Collections;assembly=mscorlib"
...
And then just use the collection:
<Menu ItemsSource="{StaticResource MenuItems}" />
...
<ContextMenu>
<MenuItem Header="View" ItemsSource="{StaticResource MenuItems}" />
</ContextMenu>

Categories