2010-06-15 83 views
0

我在ScrollViewer中有一个ItemsControl,并且当这些项目超过ScrollViewer的宽度时,它们被放入一个ContextMenu中,并显示为DropDown。我的问题是,当上下文菜单第一次加载时,它节省了菜单的大小,并且在添加/删除更多命令时不会重新绘制。WPF - 项目更改时重绘上下文菜单?

例如,面板有3个命令。 1是可见的,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和传递一个空委托上渲染,试图迫使重绘试过,但没有作品。我使用.Net 4.0。

+0

只是好奇你为什么要取消ContextMenuOpening事件?是因为你只希望它显示在左键单击还是其他东西? – devios1 2010-06-15 12:55:39

+0

是的,我想在ButtonClick上显示菜单,而不是R鼠标按钮按下 – Rachel 2010-06-15 12:58:02

回答

2

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

如果您绑定的集合到ItemsControl的,该集合必须实现INotifyCollectionChanged接口让的ItemsControl知道集合中的项目数量发生了变化,从而使该控件可以“重绘”本身。

+0

它是一个继电器命令 – Rachel 2010-06-15 14:19:58

+0

ObservableCollection好了,但我没有看到任何代码改变MenuCommands集合!代码的哪部分改变了它? – decyclone 2010-06-15 15:28:27

+0

ScrollViewer.SizeChanged事件修改了MenuCommands集合,并根据该对象是否在ScrollViewers视口内或不是... hrrm修改ObservableCollection中的项目不会触发ObservableCollection已更改事件,从而更改IsVisible属性? – Rachel 2010-06-15 16:00:15