2010-06-15 19 views
0

J'ai un ItemsControl dans un ScrollViewer, et lorsque les éléments dépassent la largeur de ScrollViewer, ils sont placés dans un ContextMenu et affichés comme DropDown à la place. Mon problème est que lorsque le menu contextuel est chargé, il enregistre la taille du menu et ne redessine pas lorsque d'autres commandes sont ajoutées/supprimées.WPF - Redessiner un menu contextuel lorsque les éléments changent?

Par exemple, un panneau a 3 commandes. 1 est visible et 2 sont dans le menu. L'affichage du menu montre les 2 commandes et dessine le contrôle, mais si vous redimensionnez le panneau de façon à ce que 2 soient visibles et qu'une seule commande soit dans le menu, il ne redessine pas le menu pour éliminer ce second élément de menu. Ou pire encore, si vous réduisez le panneau de sorte qu'aucune commande sont affichés et tous les 3 sont dans le menu, il n'affiche le top 2.

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

Voici mon 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 Derrière:

 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; 
     } 
    } 

J'ai essayé d'utiliser InvalidateVisual et passer un délégué vide rendu pour essayer de forcer un nouveau tracé, cependant ni travaux. J'utilise .Net 4.0.

+0

Juste curieux de savoir pourquoi vous annulez l'événement ContextMenuOpening? Est-ce parce que vous ne voulez que l'afficher sur un clic gauche ou quelque chose? – devios1

+0

Oui, je veux afficher le menu sur ButtonClick, pas sur le bouton R-Mouse – Rachel

Répondre

2

MenuCommandes une collection? Si c'est le cas, est-ce une ObservableCollection?

Si vous liez une collection à un ItemsControl, cette collection doit mettre en œuvre INotifyCollectionChanged Interface pour laisser le ItemsControl savoir que le nombre d'éléments de la collection a changé, de sorte que le contrôle peut « redessiner » lui-même .

+0

C'est une ObservableCollection de RelayCommands – Rachel

+0

Ok, mais je ne vois pas de code qui change la collection MenuCommands! Quelle partie du code le modifie? – decyclone

+0

L'événement ScrollViewer.SizeChanged modifie la collection MenuCommands et modifie la propriété IsVisible en fonction de si l'objet se trouve dans la fenêtre ScrollViewers ou non ... hrrm peut-être modifier un élément dans un ObservableCollection ne déclenche pas l'événement ObservableCollection modifié? – Rachel

Questions connexes