I am developing a wpf .net core 5 app. The app supports Multilanguage. This app has a UserControl
with a ContextMenu
.
The Problem: When opening the context menu for the first time it fits the width of its content which is normal.. but when changing the app language and opening the menu again its width remains without changing.. and that hides its content!
Notes: If the app starts up with Language A and then the language is changed to Language B.. when opening the menu it fits Language B content and vise versa.
I think that this is a bug with the UI engine.. however what is the best way to fix this rather than setting the width of the menu manually OnContextMenuOpening
with fixed width according to the current language? or how does it renders its size at the first time so that I can call this way every time it's opening?
CodePudding user response:
The Answer
After hours of searching I wasn't able to find a way to fix this bug without setting the width manually. even the manual way has a trick when setting the width of the submenu item as I'm going to explain in the following code:
UserControl.xaml.cs (DON'T FORGET The .ZERO "000.0)
Directly setting the width of the SubMenu
will change its header not the menu itself. also changing the width of the SubItems will not solve the problem as the bug is in the Popup itself not its items. To get around that you can use VisualTreeHelper.GetChild(DependencyObject, Int32) Method untill reaching the Popup and directly change its width or you can follow this:
private void Menu_Opened(object sender, RoutedEventArgs e)
{
if (Languages.Language == "English")
{
Menu.Width = 183;
SubMenu.Tag = 137.0;
}
else if (Languages.Language == "العربية")
{
Menu.Width = 123;
SubMenu.Tag = 117.0;
}
}
(MenuItem.SubmenuHeaderTemplateKey) Template located in App.xaml:
<Popup x:Name="Popup" Width="{Binding Tag, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=MenuItem}}" Placement="Right" HorizontalOffset="-4" IsOpen="{TemplateBinding IsSubmenuOpen}" AllowsTransparency="True" Focusable="False" PopupAnimation="Fade">
Full Template
<ControlTemplate x:Key="{x:Static MenuItem.SubmenuHeaderTemplateKey}" TargetType="{x:Type MenuItem}">
<Border Name="Border" CornerRadius="4" Margin="1" Height="25">
<Grid Margin="0,0,5,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<Path Grid.Column="0" FlowDirection="LeftToRight" Stretch="Uniform" Margin="0,5.5,0,5.5" Fill="{DynamicResource ForegroundBrush}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalAlignment="Center" Data="{Binding Uid, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=MenuItem}}"/>
<ContentPresenter x:Name="HeaderHost" Grid.Column="1" ContentSource="Header" RecognizesAccessKey="True" VerticalAlignment="Center" TextElement.FontFamily="{StaticResource Segoe Semibold}" TextElement.FontSize="13.5" TextElement.Foreground="{DynamicResource ForegroundBrush}"/>
<Path Grid.Column="2" Margin="12,6,0,6" Stretch="Uniform" VerticalAlignment="Center" Fill="{DynamicResource ForegroundBrush}" Data="M 0 0 L 0 7 L 4 3.5 Z"/>
<Popup x:Name="Popup" Width="{Binding Tag, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=MenuItem}}" Placement="Right" HorizontalOffset="-4" IsOpen="{TemplateBinding IsSubmenuOpen}" AllowsTransparency="True" Focusable="False" PopupAnimation="Fade">
<Grid>
<Border Margin="2" CornerRadius="4" BorderThickness="0" Background="{DynamicResource CardBrush}" Effect="{DynamicResource FluentDropShadowEffect}"/>
<StackPanel Margin="4" IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Cycle"/>
</Grid>
</Popup>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Border" Property="Background" Value="{DynamicResource ElementHoverBrush}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.5"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>