ScrollViewerにItemsControlがあり、アイテムがScrollViewerの幅を超えると、それらはContextMenuに入れられ、代わりにDropDownとして表示されます。私の問題は、コンテキストメニューが最初にロードされたときに、メニューのサイズを節約し、さらにコマンドが追加/削除されても再描画されないことです。
たとえば、パネルには3つのコマンドがあります。1つが表示され、2つがメニューにあります。メニューを表示すると、2つのコマンドが表示され、コントロールが描画されますが、パネルのサイズを変更して2つが表示され、メニューに1つのコマンドしか含まれていない場合、メニューが再描画されて2番目のメニュー項目が削除されません。さらに悪いことに、コマンドが表示されず、3つすべてがメニューに表示されるようにパネルを縮小すると、上位2つだけが表示されます。
これが私のコードです:
<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>
コードビハインド:
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;
cMenu.IsOpen = true;
}
}
InvalidateVisualを使用し、Renderに空のデリゲートを渡して再描画を強制しようとしましたが、どちらも機能しません。.Net4.0を使用しています。