2010-12-09 6 views
4

Im obtenir icône ligneMenu apparaissant uniquement sur la dernière ligneMenu. Si je snoop l'application que la dernière image ligneMenu a icône, alors que si je déboguer tous MenuItems semblent avoir l'image en icône. Aussi, si j'ajoute submenuItem l'icône sur menuItem disparaît une fois que j'ouvre les sous-menus et le dernier sous-menu obtient l'icône ... Une idée? PS: aussi les info-bulles sur l'élément de menu ne fonctionnent pas. Im en utilisant des contrôles caliburn micro et fluides.WPF - MenuItem manquant Icône/Image

 <ControlTemplate x:Key="dropDownButton"> 
     <ef:DropDownButton Header="{Binding DisplayName}" 
          ItemsSource="{Binding Items}" 
          LargeIcon="{Binding LargeIconPath}" 
          cm:Message.Attach="ClickAction()" 
          ef:KeyTip.Keys="{Binding KeyTip}"> 
      <ef:DropDownButton.ItemContainerStyle> 
       <Style TargetType="MenuItem"> 
        <Setter Property="Header" 
          Value="{Binding DisplayName}"/> 
        <Setter Property="Icon"> 
         <Setter.Value> 
          <Image Source="{Binding Path=IconPath}"/> 
         </Setter.Value> 
        </Setter> 
        <Setter Property="ItemsSource" 
          Value="{Binding Items}"/> 
        <Setter Property="cm:Message.Attach" 
          Value="ClickAction()"/> 
        <Setter Property="ef:KeyTip.Keys" 
          Value="{Binding KeyTip}"/> 
        <Setter Property="ToolTip"> 
         <Setter.Value> 
          <ef:ScreenTip Title="{Binding DisplayName}" 
              HelpTopic="ScreenTip help ..." 
              Image="{Binding LargeIconPath}" 
              Text="Text for ScreenTip"/> 
         </Setter.Value> 
        </Setter> 
       </Style> 
      </ef:DropDownButton.ItemContainerStyle> 
      <ef:DropDownButton.ToolTip> 
       <ef:ScreenTip Title="{Binding DisplayName}" 
           HelpTopic="ScreenTip help ..." 
           Image="{Binding LargeIconPath}" 
           Text="Text for ScreenTip"/> 
      </ef:DropDownButton.ToolTip> 
     </ef:DropDownButton> 
+1

à mon humble avis la solution à la question similaire: « http://stackoverflow.com/questions/6177550/menuitem-style-with-icon-creates-only-one-icon » est un meilleur. –

Répondre

7

Vous définissez Icon propriété à un contrôle Image dans Style. Maintenant, une seule copie de Style est créée et, par conséquent, une seule copie de Image est créée. Maintenant, tout contrôle ne peut avoir qu'un seul parent à la fois. Alors, quand il est attribué au dernier MenuItem, il est retiré de MenuItem précédents contrôles. Pour résoudre ce problème, utilisez Templates.

Au lieu de définir Header propriété, définissez HeaderTemplate:

  <Setter Property="HeaderTemplate"> 
       <Setter.Value> 
        <DataTemplate> 
         <Grid> 
          <Grid.ColumnDefinitions> 
           <ColumnDefinition Width="Auto" /> 
           <ColumnDefinition Width="*" /> 
          </Grid.ColumnDefinitions> 
          <Image Grid.Column="0" 
            Source="{Binding Path=IconPath}" /> 
          <TextBlock Grid.Column="1" 
             Text="{Binding DisplayName}" /> 
         </Grid> 
        </DataTemplate> 
       </Setter.Value> 
      </Setter> 

Je ne suis pas sûr de ce que les propriétés sont exposées par la boîte à outils de contrôle que vous utilisez. Mais, je suis sûr qu'ils doivent avoir une propriété de modèle.

Après avoir fait cela, vous n'avez pas besoin de définir Icon propriété dans le style.

+0

en essayant d'utiliser cela, mais ce n'est pas clair pour moi. Im obtenir Erreur: « System.Windows.Controls.Grid » est pas une valeur valide pour la propriété « System.Windows.Controls.HeaderedContentControl.HeaderTemplate » sur un poseur. – no9

+0

Mon erreur. Vous devez l'envelopper dans 'DataTemplate'. – decyclone

0

fonctionne comme ceci:

 <DataTemplate x:Key="MenuItemHeaderTemplate"> 
     <Grid> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="Auto" /> 
       <ColumnDefinition Width="*" /> 
      </Grid.ColumnDefinitions> 
      <Image Grid.Column="0" Source="{Binding Path=IconPath}" /> 
      <Label Grid.Column="1" Content="{Binding DisplayName}" />    
     </Grid> 
    </DataTemplate> 


    <ControlTemplate x:Key="dropDownButton"> 
     <ef:DropDownButton Header="{Binding DisplayName}" 
          ItemsSource="{Binding Items}" 
          LargeIcon="{Binding LargeIconPath}" 
          cm:Message.Attach="ClickAction()" 
          ef:KeyTip.Keys="{Binding KeyTip}"> 
      <ef:DropDownButton.ItemContainerStyle> 
       <Style TargetType="MenuItem"> 
        <Setter Property="HeaderTemplate" Value="{StaticResource MenuItemHeaderTemplate}" />         
        <Setter Property="ItemsSource" 
          Value="{Binding Items}"/> 
        <Setter Property="cm:Message.Attach" 
          Value="ClickAction()"/> 
        <Setter Property="ef:KeyTip.Keys" 
          Value="{Binding KeyTip}"/> 
        <Setter Property="ToolTip"> 
         <Setter.Value> 
          <ef:ScreenTip Title="{Binding DisplayName}" 
              HelpTopic="ScreenTip help ..." 
              Image="{Binding LargeIconPath}" 
              Text="Text for ScreenTip"/> 
         </Setter.Value> 
        </Setter> 
       </Style> 
      </ef:DropDownButton.ItemContainerStyle> 
      <ef:DropDownButton.ToolTip> 
       <ef:ScreenTip Title="{Binding DisplayName}" 
           HelpTopic="ScreenTip help ..." 
           Image="{Binding LargeIconPath}" 
           Text="Text for ScreenTip"/> 
      </ef:DropDownButton.ToolTip> 
     </ef:DropDownButton> 
0

-je utiliser avec succès les entrées suivantes dans un ResourceDictionary:

<!-- Define non-shared image to avoid loss of menu icons --> 
<Image x:Key="MenuIconImage" Height="16" Width="16" x:Shared="false"> 
    <Image.Source> 
     <DrawingImage Drawing="{Binding Icon}" /> 
    </Image.Source> 
</Image> 

<Style TargetType="{x:Type MenuItem}" BasedOn="{StaticResource {x:Type MenuItem}}"> 
    <Setter Property="Header" Value="{Binding DisplayName /> 
    <Setter Property="Icon" Value="{StaticResource MenuIconImage}" /> 
</Style> 
0

Pour une approche de raison lorsque l'image est ressource statique avec x: Shared = false Ne fait pas travaille pour moi. Seul le dernier élément de menu affiche l'icône. J'ai essayé à la fois StaticResource et DynamicResource. Voici ma solution:

public class MenuItemIconHelper 
{ 
    #region ImageSource Icon 

    public static readonly DependencyProperty IconProperty = DependencyProperty.RegisterAttached("Icon", typeof(ImageSource), typeof(MenuItemIconHelper), new PropertyMetadata(default(ImageSource), IconPropertyChangedCallback)); 

    private static void IconPropertyChangedCallback(DependencyObject obj, DependencyPropertyChangedEventArgs e) 
    { 
     var i = (MenuItem)obj; 

     if (e.NewValue != null) 
      i.Icon = new Image() {Source = (ImageSource)e.NewValue}; 
     else 
      i.Icon = null; 
    } 

    public static void SetIcon(DependencyObject element, ImageSource value) 
    { 
     element.SetValue(IconProperty, value); 
    } 

    public static ImageSource GetIcon(DependencyObject element) 
    { 
     return (ImageSource)element.GetValue(IconProperty); 
    } 

    #endregion 
} 

Exemple:

<Style x:Key="CommandMenuItemStyle" TargetType="MenuItem"> 
<Setter Property="cb:MenuItemIconHelper.Icon" Value="car1.png" /> 
<Setter Property="Header" Value="{Binding Name}" /> 

Je considère qu'il est plus lisible que l'utilisation des ressources et vous n'avez pas besoin de changer de HeaderTemplate MenuItem. Vous pouvez également implémenter un mécanisme de mise en cache pour ImageSource ou Image.

Questions connexes