WPF - 项目更改时重绘上下文菜单?

时间:2010-06-15 12:51:28

标签: wpf dynamic refresh contextmenu redraw

我在ScrollViewer中有一个ItemsControl,当项目超过ScrollViewer的宽度时,它们被放入ContextMenu并显示为DropDown。我的问题是,当首次加载上下文菜单时,它会保存保存菜单的大小,并且在添加/删除更多命令时不会重绘。

例如,面板有3个命令。 1显示,2显示在菜单中。查看菜单显示2个命令并绘制控件,但如果您调整面板大小以使2可见且菜单中只有1个命令,则不会重绘菜单以消除该第二个菜单项。或者更糟糕的是,如果你缩小面板以便没有显示任何命令而所有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上传递一个空委托来尝试强制重绘,但是都不起作用。我正在使用.Net 4.0。

1 个答案:

答案 0 :(得分:2)

MenuCommands是一个集合吗?如果是,是ObservableCollection吗?

如果您将一个集合绑定到 ItemsControl ,该集合必须实现 INotifyCollectionChanged 界面,让 ItemsControl 知道其中的项目数量集合已经改变,因此控件可以“重绘”自己。