Cannot show ContextMenu programmatically when instantiating it from Resources
Hi,
I am experimenting on how to show context menu using triggers other than Right-click.
The following code works well:
XAML
C++
Now I changed the XAML to use ContextMenu from a Resource
Now clicking the button doesn't show the context menu. What did I do wrong ?
I also observed that after clicking the button, the right-click event also ceased to work (i.e. context menu is not shown either with right-click).
Thanks.
I am experimenting on how to show context menu using triggers other than Right-click.
The following code works well:
XAML
Code: Select all
<UserControl x:Class="NoesisTutorial.ContextMenu"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:noesis="clr-namespace:Noesis"
xmlns:local="clr-namespace:NoesisTutorial"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid Background="AntiqueWhite">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition Height="40"></RowDefinition>
</Grid.RowDefinitions>
<Grid x:Name="MyGrid" Grid.Row="0" Background="WhiteSmoke"
ContextMenuService.Placement="Center"
ContextMenuService.IsEnabled="True"
ContextMenuService.PlacementTarget="{Binding ElementName=MyGrid}"
>
<Grid.ContextMenu>
<ContextMenu>
<MenuItem Header="Test1"></MenuItem>
<MenuItem Header="Test2"></MenuItem>
</ContextMenu>
</Grid.ContextMenu>
</Grid>
<Button x:Name="MyButton" Grid.Row="1" Click="Button_Click">Click to open ContextMenu</Button>
</Grid>
</UserControl>
Code: Select all
void ContextMenu::Button_Click(BaseComponent* sender, const RoutedEventArgs & e) {
auto grid = this->FindName<Grid>("MyGrid");
auto menu = grid->GetContextMenu();
menu->SetIsOpen(true);
}
Code: Select all
<UserControl x:Class="NoesisTutorial.ContextMenu"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:noesis="clr-namespace:Noesis"
xmlns:local="clr-namespace:NoesisTutorial"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<ContextMenu x:Key="myContextMenu">
<MenuItem Header="Test1"></MenuItem>
<MenuItem Header="Test2"></MenuItem>
</ContextMenu>
</UserControl.Resources>
<Grid Background="AntiqueWhite">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition Height="40"></RowDefinition>
</Grid.RowDefinitions>
<Grid x:Name="MyGrid" Grid.Row="0" Background="WhiteSmoke"
ContextMenuService.Placement="Center"
ContextMenuService.IsEnabled="True"
ContextMenuService.PlacementTarget="{Binding ElementName=MyGrid}"
ContextMenu="{StaticResource myContextMenu}"
>
</Grid>
<Button x:Name="MyButton" Grid.Row="1" Click="Button_Click">Click to open ContextMenu</Button>
</Grid>
</UserControl>
I also observed that after clicking the button, the right-click event also ceased to work (i.e. context menu is not shown either with right-click).
Thanks.
Re: Cannot show ContextMenu programmatically when instantiating it from Resources
Try this, I can't test it now, (nspired from this: https://stackoverflow.com/questions/276 ... -reference )
simply change to ContextMenu="{Binding myContextMenu}" instead StaticResource (it is working for me, but I binding text instead context menu) orIt is not working because Grid dont have dataContext for resource.
simply change to ContextMenu="{Binding myContextMenu}" instead StaticResource (it is working for me, but I binding text instead context menu) or
Code: Select all
<UserControl.Resources>
<dataContextMenu x:Key="cm">
<ContextMenu x:Key="myContextMenu">
<MenuItem Header="Test1"></MenuItem>
<MenuItem Header="Test2"></MenuItem>
</ContextMenu>
</dataContextMenu>
</UserControl.Resources>
// ..
<Grid x:Name="MyGrid" Grid.Row="0" Background="WhiteSmoke"
DataContext="{StaticResource cm}"
ContextMenuService.Placement="Center"
ContextMenuService.IsEnabled="True"
ContextMenuService.PlacementTarget="{Binding ElementName=MyGrid}"
ContextMenu="{Binding myContextMenu}"
>
</Grid>Re: Cannot show ContextMenu programmatically when instantiating it from Resources
@Wanderer, thanks for the workaround. However, I need to know why using StaticResource doesn't work (while in WPF it is working). I am thinking to put ContextMenu in the resource, customize it using DataTemplate, then share it across the components.
Re: Cannot show ContextMenu programmatically when instantiating it from Resources
Found another issue. When trying to bind IsOpen property of the context menu, the view freezes and nothing happens.
# The reason that I was trying to bind IsOpen is so that I can trigger the ContextMenu from VM code (without needing to directly access the View layer).
Slightly modify the XAML from the first code above reproduce it. It doesn't matter that "AnyProperty" exists or not.
# The reason that I was trying to bind IsOpen is so that I can trigger the ContextMenu from VM code (without needing to directly access the View layer).
Slightly modify the XAML from the first code above reproduce it. It doesn't matter that "AnyProperty" exists or not.
Code: Select all
<UserControl x:Class="NoesisTutorial.ContextMenu"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:noesis="clr-namespace:Noesis"
xmlns:local="clr-namespace:NoesisTutorial"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid Background="AntiqueWhite">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition Height="40"></RowDefinition>
</Grid.RowDefinitions>
<Grid x:Name="MyGrid" Grid.Row="0" Background="WhiteSmoke"
ContextMenuService.Placement="Center"
ContextMenuService.IsEnabled="True"
ContextMenuService.PlacementTarget="{Binding ElementName=MyGrid}"
>
<Grid.ContextMenu>
<ContextMenu IsOpen="{Binding AnyProperty}">
<MenuItem Header="Test1"></MenuItem>
<MenuItem Header="Test2"></MenuItem>
</ContextMenu>
</Grid.ContextMenu>
</Grid>
<Button x:Name="MyButton" Grid.Row="1" Click="Button_Click">Click to open ContextMenu</Button>
</Grid>
</UserControl>
-
-
sfernandez
Site Admin
- Posts: 3364
- Joined:
Re: Cannot show ContextMenu programmatically when instantiating it from Resources
It is a bug in Noesis, because our code was assuming that ContextMenu was defined inside the ContextMenu property of the target element. Could you please report it in our bugtracker?I need to know why using StaticResource doesn't work (while in WPF it is working). I am thinking to put ContextMenu in the resource, customize it using DataTemplate, then share it across the components.
I was able to reproduce it. It seems that ContextMenu closes while trying to open it, but mouse capture is not released so it doesn't interact with the rest of the View anymore.Found another issue. When trying to bind IsOpen property of the context menu, the view freezes and nothing happens.
Could you please report this one too?
Thanks for your cooperation.
Re: Cannot show ContextMenu programmatically when instantiating it from Resources
I filed the issues: #001151 and #001152.
-
-
sfernandez
Site Admin
- Posts: 3364
- Joined:
Re: Cannot show ContextMenu programmatically when instantiating it from Resources
Hi! This is an old thread, but I have a similar issue in latest version 3.2.3 - I want to programmatically show context menu from resources, but it either doesn't show or behaves weird.
This can be reproduced if I modify "Buttons" example from SDK like this:
Resources.xaml
MainWindow.xaml
ViewModel.cpp
The menu doesn't appear in Noesis, but appears in WPF.
However, it appears correctly If I place the menu inside MainWindow's resources. So it seems the culprit is application resources, but what do they miss?
It also sort of works if I call SetNodeParent on the menu before opening to "attach" it to the button. But things seem to go weird. It is hard to reproduce on minimal example, but we get issues like clicking on non-MenuItem inside the menu (we have a header in its template) causing the menu to close and reopen again. Focus behavior also breaks: the button that shows the menu is inside an engaged control and when I press ESC the menu doesn't close, instead the control is disengaged and focus can now move freely outside the menu that just stays on screen.
Maybe it is something in our code, but it doesn't happen if I open the menu in "natural way" via the right click.
Do you have any advice?
This can be reproduced if I modify "Buttons" example from SDK like this:
Resources.xaml
Code: Select all
<ContextMenu x:Key="AMenu">
<MenuItem Header="111"/>
<MenuItem Header="222"/>
<MenuItem Header="333"/>
</ContextMenu>Code: Select all
<Button x:Name="ExitButton" Grid.Row="5" Content="EXIT" Command="{Binding ExitCommand}"
CommandParameter="{Binding ContextMenu, RelativeSource={RelativeSource Self}}"
ContextMenu="{StaticResource AMenu}">Code: Select all
void ViewModel::Exit(BaseComponent* arg)
{
DynamicCast<ContextMenu*>(arg)->SetIsOpen(true);
NS_LOG_INFO("Exit Game");
}However, it appears correctly If I place the menu inside MainWindow's resources. So it seems the culprit is application resources, but what do they miss?
It also sort of works if I call SetNodeParent on the menu before opening to "attach" it to the button. But things seem to go weird. It is hard to reproduce on minimal example, but we get issues like clicking on non-MenuItem inside the menu (we have a header in its template) causing the menu to close and reopen again. Focus behavior also breaks: the button that shows the menu is inside an engaged control and when I press ESC the menu doesn't close, instead the control is disengaged and focus can now move freely outside the menu that just stays on screen.
Maybe it is something in our code, but it doesn't happen if I open the menu in "natural way" via the right click.
Do you have any advice?
-
-
sfernandez
Site Admin
- Posts: 3364
- Joined:
Re: Cannot show ContextMenu programmatically when instantiating it from Resources
This is a bug, could you please report in our bugtracker?
Who is online
Users browsing this forum: Bing [Bot] and 1 guest