Reputation: 15
I created a ContextMenu with several MenuItems. When the user clicks on a Label the ContextMenu disappear but I want to keep it Opened. The aims is to avoid the reopen the menu when the user miss click a textbox or a checkbox.
The XAML code is :
<ContextMenu
x:Key="contextMenuListeNew"
Name="contextMenuUser"
StaysOpen="True"
>
<MenuItem
Header="Justifier"
Name="contextMenuJustifier"
StaysOpenOnClick="True"
>
</MenuItem>
<MenuItem
Header="Corriger"
Name="MenuItemModifier"
StaysOpenOnClick="True"
IsSubmenuOpen="True"
MouseLeftButtonDown="MenuItem_MouseLeftButtonDown"
>
<StackPanel
Orientation="Horizontal"
Margin="2,0,0,0"
MouseLeftButtonDown="MenuItem_MouseLeftButtonDown"
>
<Label
Name="LabelDispo"
Content="Dispo"
MouseLeftButtonDown="MenuItem_MouseLeftButtonDown"
/>
<TextBox
Name="TextBoxDispoBrute"
Text=""
VerticalContentAlignment="Center"
MouseLeftButtonDown="MenuItem_MouseLeftButtonDown"
Width="60"
/>
<Label
Name="LabelPourcentage"
MouseLeftButtonDown="MenuItem_MouseLeftButtonDown"
Content="%" />
<CheckBox
Name="CheckBoxAllCells"
Margin="0,5,0,0"
MouseLeftButtonDown="MenuItem_MouseLeftButtonDown"
Content="dont les 100%"
/>
</StackPanel>
<StackPanel
Orientation="Horizontal"
MouseLeftButtonDown="MenuItem_MouseLeftButtonDown"
Margin="0,5,0,0">
<Label
Content="Commentaire"
MouseLeftButtonDown="MenuItem_MouseLeftButtonDown"/>
<TextBox
Name="TextBoxCommentaireDispo"
Height="25"
MouseLeftButtonDown="MenuItem_MouseLeftButtonDown"
Width="135"
VerticalContentAlignment="Center"
Text=""
/>
</StackPanel>
<Separator />
<Button
Content="OK"
MouseLeftButtonDown="MenuItem_MouseLeftButtonDown"
Name="ButtonValiderDispo"
Width="80"
Height="20"
/>
</MenuItem>
<MenuItem
Header="RéInitialiser"
Name="MenuItemReset"
StaysOpenOnClick="True"
>
</MenuItem>
</ContextMenu>
It looks like something like that ContextMenu
So when the user click on "Dispo" or "Commentaire" the contextmenu will close.
With the property StaysOpenOnClick="True" the MenuItem stays open only if its contains only a Name to click.
So "Justifier" and Réinitialiser" stays open thanks to this property. But it does not works when a add a stack panel with several elements like in the item "Corriger".
I found a first kind of workaround with the method :
Click="MenuItem_Click" that is placed on the MenuItem with this implementation :
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
(e.OriginalSource as MenuItem).StaysOpenOnClick = true;
(e.OriginalSource as MenuItem).IsSubmenuOpen = true;
(e.Source as MenuItem).StaysOpenOnClick = true;
(e.Source as MenuItem).IsSubmenuOpen = true;
}
With this code the ContextMenu stays open only after the second click. On the first One the ContextMenu steal close but after it stays opened.
Do you know how to do it even at the first Click ?
Best Regards,
Upvotes: 1
Views: 1093
Reputation: 21999
See this answer, to prevent menu item from closing menu you have to use a trick where your content is put inside MenuItem.Header
(can be nested inside other MenuItem
):
<Grid Background="White">
<Grid.ContextMenu>
<ContextMenu StaysOpen="True"> <!-- important -->
<MenuItem Header="1" />
<MenuItem Header="2"
StaysOpenOnClick="True"> <!-- important -->
<MenuItem StaysOpenOnClick="True"> <!-- nested MenuItem -->
<MenuItem.Header>
<TextBox Width="60" /> <!-- content goes here -->
</MenuItem.Header>
</MenuItem>
</MenuItem>
<MenuItem Header="3" />
</ContextMenu>
</Grid.ContextMenu>
</Grid>
Upvotes: 0
Reputation: 13438
Basically, you have a little misconception of what happens with the content of a MenuItem
. Content elements that are not MenuItem
or Separator
themself, will be wrapped in MenuItem
in the visual tree. So the following
<MenuItem Header="Corriger" StaysOpenOnClick="True">
<StackPanel Orientation="Horizontal" Margin="2,0,0,0">
<Label Content="Dispo" />
<TextBox Text="" VerticalContentAlignment="Center" Width="60" />
<Label Content="%" />
<CheckBox Margin="0,5,0,0" Content="dont les 100%" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,5,0,0">
<Label Content="Commentaire"/>
<TextBox Height="25" Width="135" VerticalContentAlignment="Center" Text="" />
</StackPanel>
<Separator />
<Button Content="OK" Width="80" Height="20" />
</MenuItem>
will (roughly and incompletely) translate into this:
<MenuItem Header="Corriger" StaysOpenOnClick="True">
<MenuItem>
<MenuItem.Header>
<StackPanel Orientation="Horizontal" Margin="2,0,0,0">
<Label Content="Dispo" />
<TextBox Text="" VerticalContentAlignment="Center" Width="60" />
<Label Content="%" />
<CheckBox Margin="0,5,0,0" Content="dont les 100%" />
</StackPanel>
</MenuItem.Header>
</MenuItem>
<MenuItem>
<MenuItem.Header>
<StackPanel Orientation="Horizontal" Margin="0,5,0,0">
<Label Content="Commentaire"/>
<TextBox Height="25" Width="135" VerticalContentAlignment="Center" Text="" />
</StackPanel>
</MenuItem.Header>
</MenuItem>
<Separator />
<MenuItem>
<MenuItem.Header>
<Button Content="OK" Width="80" Height="20" />
</MenuItem.Header>
</MenuItem>
</MenuItem>
You see the missing StaysOpenOnClick="True"
on the inner auto-generated items, right?
Solution: I suspect you don't actually need so many menu items on this inner level, but you need to make the menu items explicit or use some style to ensure the StaysOpenOnClick
. Here is a solution with an explicit item:
<MenuItem Header="Corriger" StaysOpenOnClick="True">
<MenuItem StaysOpenOnClick="True">
<MenuItem.Header>
<StackPanel>
<StackPanel Orientation="Horizontal" Margin="2,0,0,0">
<Label Content="Dispo" />
<TextBox Text="" VerticalContentAlignment="Center" Width="60" />
<Label Content="%" />
<CheckBox Margin="0,5,0,0" Content="dont les 100%" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,5,0,0">
<Label Content="Commentaire"/>
<TextBox Height="25" Width="135" VerticalContentAlignment="Center" Text="" />
</StackPanel>
<Separator />
<Button Content="OK" Width="80" Height="20" />
</StackPanel>
</MenuItem.Header>
</MenuItem>
</MenuItem>
If you don't like the highlight of the whole area, use multiple explicit sub-menu items or more explicit design with style and/or templates.
Upvotes: 0