2017-08-29 3 views
1

Dans les ressources TreeView, j'ai un HierarchicalDataTemplate qui définit également le style du menu contextuel. Le but est de pouvoir définir par programmation un MenuItem s en spécifiant un nom d'icône en tant que Tag et d'afficher ensuite l'icône de droite sur l'affichage frontal.L'icône liée aux données du menu contextuel de WPF apparaît uniquement lors de l'inspection

<StackPanel.ContextMenu> 
    <ContextMenu ItemsSource="{Binding MenuItems}"> 
     <ContextMenu.Resources> 
      <Style TargetType="{x:Type MenuItem}"> 
       <Setter Property="Icon"> 
        <Setter.Value> 
         <local:StringToIcon IconName="{Binding Tag, RelativeSource={RelativeSource AncestorType=MenuItem}}" /> 
        </Setter.Value> 
       </Setter> 
      </Style> 
     </ContextMenu.Resources> 
    </ContextMenu> 
</StackPanel.ContextMenu> 

StringToIcon est un autre contrôle que, pour les essais, ressemble comme ça. Il est pris en charge par la propriété de dépendance IconName.

<UserControl x:Class="MyApp.Components.StringToIcon" 
      ... 
      Name="StringIconControl"> 
    <Image DataContext="{Binding ElementName=StringIconControl}"> 
     <Image.Style> 
      <Style TargetType="{x:Type Image}"> 
       <Style.Triggers> 
        <DataTrigger Binding="{Binding IconName}" Value="Refresh"> 
         <Setter Property="Source" Value="{StaticResource IconRefresh}"/> 
        </DataTrigger> 
       </Style.Triggers> 
      </Style> 
     </Image.Style> 
    </Image> 
</UserControl> 

IconRefresh est tout simplement une ressource disponible à l'échelle mondiale:

<BitmapImage x:Shared="False" x:Key="IconRefresh" UriSource="pack://application:,,,/Resources/Icons/refresh.png" /> 

Lors du démarrage de l'application, aucune des icônes de rafraîchissement du menu contextuel apparaît. Ils sont tous vides. Je reçois des erreurs de liaison, que je suis amené à croire est due aux menus contextuels ne pas être dans l'arbre visuel:

Vous ne trouvez pas la source pour la liaison avec référence « RelativeSource FindAncestor, AncestorType = » System.Windows.Controls .MenuItem ', AncestorLevel =' 1 ''. BindingExpression: Path = Tag; DataItem = null; l'élément cible est 'StringToIcon' (Name = 'StringIconControl'); propriété cible est « iconName » (type « chaîne »)

Cependant, lors de l'utilisation Snoop pour inspecter le menu, l'ensemble des fixations et propriété de dépendance sont corrects. Après l'inspection de cette manière, l'icône d'actualisation inspectée apparaît miraculeusement, comme si elle forçait les réassorts à réévaluer. Vous pouvez le faire, un par un, à chaque instance de cette icône et ils apparaîtront.

Comment réparer cette liaison paresseuse qui semble se produire ici? Ou y a-t-il autre chose en jeu? J'ai vu un autre article qui suggérait de rattacher le contexte des données de menu à quelque chose que est dans l'arborescence visuelle, mais je ne vois pas ce que ce serait dans cette instance.

Répondre

0

La solution éventuelle au problème de liaison était de faire une nouvelle classe pour tenir les détails de l'élément de menu: au style de l'élément de menu

public class BindableMenuItem 
{ 
    public BindableMenuItem(string name, ICommand command) 
    { 
     this.Name = name; 
     this.Command = command; 
    } 
    public string Name { get; set; } 
    public ICommand Command { get; set; } 
    public string IconName { get; set; } 
    public ObservableCollection<BindableMenuItem> Children { get; set; } 
} 

Ce fut alors ligoté comme suit:

<Style TargetType="MenuItem"> 
    <Setter Property="Header" Value="{Binding Name}" /> 
    <Setter Property="Command" Value="{Binding Command}" /> 
    <Setter Property="ItemsSource" Value="{Binding Children}" /> 
    <Setter Property="Icon"> 
     <Setter.Value> 
      <local:StringToIcon IconName="{Binding IconName}" /> 
     </Setter.Value> 
    </Setter> 
</Style> 

Cela fonctionne probablement parce que la liaison ne dépend pas de l'existence d'une source relative dans l'arborescence visuelle et qu'elle a plutôt une classe de modèle concrète à utiliser.

Toutefois, il existe toujours un problème avec ce qui précède concernant plusieurs instances de style. Je posterai une autre question pour ça.