WPF - Redrawing a Context Menu when Items change?
Posted
by Rachel
on Stack Overflow
See other posts from Stack Overflow
or by Rachel
Published on 2010-06-15T12:51:28Z
Indexed on
2010/06/15
12:52 UTC
Read the original article
Hit count: 564
I have a ItemsControl in a ScrollViewer, and when the items exceed the width of the ScrollViewer they are put into a ContextMenu and shown as a DropDown instead. My problem is that when the Context Menu is first loaded, it saves the saves the size of the Menu and does not redraw when more commands get added/removed.
For example, a panel has 3 commands. 1 is visible and 2 are in the Menu. Viewing the menu shows the 2 commands and draws the control, but then if you resize the panel so 2 are visible and only 1 command is in the menu, it doesn't redraw the menu to eliminate that second menu item. Or even worse, if you shrink the panel so that no commands are shown and all 3 are in the Menu, it will only show the top 2.
Here's my code:
<Button Click="DropDownMenu_Click"
ContextMenuOpening="DropDownMenu_ContextMenuOpening">
<Button.ContextMenu>
<ContextMenu ItemsSource="{Binding Path=MenuCommands}" Placement="Bottom">
<ContextMenu.Resources>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Command" Value="{Binding Path=Command}" />
<Setter Property="Visibility" Value="{Binding Path=IsVisible, Converter={StaticResource ReverseBooleanToVisibilityConverter}}"/>
</Style>
</ContextMenu.Resources>
<ContextMenu.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=DisplayName}" />
</DataTemplate>
</ContextMenu.ItemTemplate>
</ContextMenu>
</Button.ContextMenu>
</Button>
Code Behind:
void DropDownMenu_ContextMenuOpening(object sender, ContextMenuEventArgs e)
{
Button b = sender as Button;
b.ContextMenu.IsOpen = false;
e.Handled = true;
}
private void DropDownMenu_Click(object sender, RoutedEventArgs e)
{
Button b = sender as Button;
ContextMenu cMenu = b.ContextMenu;
if (cMenu != null)
{
cMenu.PlacementTarget = b;
cMenu.Placement = System.Windows.Controls.Primitives.PlacementMode.Bottom;
}
}
I have tried using InvalidateVisual and passing an empty delegate on Render to try and force a redraw, however neither works. I'm using .Net 4.0.
© Stack Overflow or respective owner