0

ScrollViewerにItemsControlがあり、アイテムがScrollViewerの幅を超えると、それらはContextMenuに入れられ、代わりにDropDownとして表示されます。私の問題は、コンテキストメニューが最初にロードされたときに、メニューのサイズを節約し、さらにコマンドが追加/削除されても再描画されないことです。

たとえば、パネルには3つのコマンドがあります。1つが表示され、2つがメニューにあります。メニューを表示すると、2つのコマンドが表示され、コントロールが描画されますが、パネルのサイズを変更して2つが表示され、メニューに1つのコマンドしか含まれていない場合、メニューが再描画されて2番目のメニュー項目が削除されません。さらに悪いことに、コマンドが表示されず、3つすべてがメニューに表示されるようにパネルを縮小すると、上位2つだけが表示されます。

https://i193.photobucket.com/albums/z197/Lady53461/ContextMenuRedraw.jpg

これが私のコードです:

<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を使用しています。

4

1 に答える 1

2

MenuCommands はコレクションですか? もしそうなら、それは ObservableCollection ですか?

コレクションをItemsControlにバインドする場合、そのコレクションはINotifyCollectionChangedインターフェイスを実装して、コレクション内の項目の数が変更されたことをItemsControlに通知し、コントロール自体を「再描画」できるようにする必要があります。

于 2010-06-15T14:07:52.020 に答える