2009-03-13 9 views
9

J'essaie de modifier le style par défaut du ContextMenu dans WPF.Style ContextMenu par défaut - WPF

Normalement, vous pouvez créer une copie de la valeur par défaut dans Expression Blend à l'aide de l'option de menu Edit Control Parts (Template)> Edit a Copy. Cependant, je ne peux pas savoir comment faire cela avec un ContextMenu. Une idée de comment je peux modifier le style par défaut?

J'essaie de désactiver le côté gauche du menu contextuel où les icônes sont normalement affichées.

Merci!

Mise à jour: Peut-être que je n'étais pas clair sur la suppression des icônes. Par exemple, si vous avez un menu contextuel sans icônes alors tout le côté gauche du menu est un espace gaspillé. Je voudrais modifier le style par défaut de l'arrière-plan du menu contextuel pour le supprimer. Simplement je ne sais pas comment accéder à ce style par défaut.

+0

Luke, avez-vous résolu ce problème? Je suis un peu confus par toutes ces différentes idées ci-dessous. Merci pour tout indice! –

+0

Oui, j'ai utilisé la réponse ci-dessous pour obtenir le modèle et le modifier à partir de là. – Luke

Répondre

10

Pour les modèles et les styles qui ne sont pas accessibles via l'interface d'expression (comme le modèle ContextMenu) vous pouvez utiliser le code suivant pour extraire le modèle:

Dim sb As System.Text.StringBuilder = New System.Text.StringBuilder 
Using Writer As TextWriter = New StringWriter(sb) 
    System.Windows.Markup.XamlWriter.Save(ContextMenu.Template, Writer) 
End Using 
Debug.Write(sb.ToString) 

ou en C#

var str = new StringBuilder(); 
using (var writer = new StringWriter(str)) 
    XamlWriter.Save(ContextMenu.Template, writer); 
Debug.Write(str); 
+4

Veuillez noter que pour obtenir un modèle dans un ContextMenu, vous devez au moins ajouter un objet MenuItem à sa collection Items. Sinon, le ContextMenu.Template est null. –

+0

J'aime Stack Overflow. Merci beaucoup pour ces réponses, exactement ce dont j'avais besoin aussi. – scobi

2

En fait, l'espace ne fait pas partie du menu contextuel, il fait partie de MenuItem. Il suffit donc de faire glisser un objet MenuItem dans votre fenêtre dans l'expression blend et de créer une copie du contrôle. Espérons que votre déclaration ContextMenu est la suivante

<ContextMenu > 
    <MenuItem Header="Copy"/> 
    <MenuItem Header="Paste"/> 
    <MenuItem Header="Clear"/> 
</ContextMenu> 

Et dans votre MenuItem ControlTemplate vous pouvez voir l'espace ci-dessous. Alors, retirez l'icône et la première colonne de la grille que j'ai marqué dans la capture d'écran.

alt text

+0

Eh bien cela me donne le style par défaut pour le MenuItem, mais il ne me donne pas le style ContextMenu. Expression Blend ne me laisse pas ajouter un ContextMenu à la fenêtre. – Luke

+0

Il affiche une erreur, "ContextMenu ne peut pas avoir de parent logique ou visuel" si j'ajoute le ContextMenu à la fenêtre. – Luke

+0

Oui, il existe également des styles dans le menu contextuel pour le menu de gauche qui doit être supprimé. Ce sont les styles ContextMenu auxquels je ne peux pas accéder à l'aide de l'interface Expression. J'ai posté une solution ci-dessous pour extraire le modèle en utilisant le code. – Luke

0

L'espace supplémentaire sur la gauche est due à la marque peu de contrôle qui apparaît lorsque vous définissez IsCheckable et IsChecked à true sur MenuItem.

La coche est dans le modèle pour MenuItem, donc si vous modifiez cela, vous pouvez l'enlever.

+0

La propriété 'IsCheckable' affecte l'interaction de l'utilisateur avec un élément de menu, et non si la zone de contrôle/d'icône est affichée dans le menu. En fait, la valeur par défaut est déjà "False". Le paramétrer sur "True" casse simplement la case à cocher pour basculer automatiquement chaque fois que l'utilisateur sélectionne cet élément de menu. –

7

J'ai trouvé le moyen facile d'obtenir le modèle ContextMenu dans le mélange:

  1. J'ai ajouté un ContextMenu à un butto n avec quelques menuitems.
  2. Sous "divers" dans le volet des propriétés, il y a un élément groupé pour ContextMenu.
  3. Ouvrir cette page. Vous trouverez les propriétés Style et Modèle habituelles.
  4. Cliquez sur le carré pour le menu contextuel, puis sélectionnez Convertir en Nouvelle ressource ...

Voilà. Choisissez où vous voulez que le modèle/style soit mis, et vous avez terminé.

Voici le balisage que j'avais:

<StackPanel x:Name="LayoutRoot"> 
    <Button Content="Click for ContextMenu" Width="30" HorizontalAlignment="Center" VerticalAlignment="Center"> 
     <Button.ContextMenu> 
      <ContextMenu Template="{DynamicResource ContextMenuControlTemplate1}" Style="{DynamicResource ContextMenuStyle1}"> 
       <MenuItem Header="File"/> 
       <MenuItem Header="Edit"/> 
       <MenuItem Header="View"/> 
       <MenuItem Header="Recent Files"/> 
        <MenuItem Header="file1.txt"/> 
        <MenuItem Header="file2.txt"/> 
      </ContextMenu> 
     </Button.ContextMenu> 
    </Button> 
</StackPanel> 

Et le style/template je suis:

<Style x:Key="ContextMenuStyle1" TargetType="{x:Type ContextMenu}"> 
    <Setter Property="Background" Value="{DynamicResource MenuBackgroundBrush}"/> 
    <Setter Property="BorderThickness" Value="1"/> 
    <Setter Property="BorderBrush" Value="{DynamicResource WindowBorderBrush}"/> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type ContextMenu}"> 
       <Border Uid="Border_93"> 
        <Border.Style> 
         <Style TargetType="{x:Type Border}"> 
          <Setter Property="Tag" Value="{DynamicResource {x:Static SystemParameters.DropShadowKey}}"/> 
          <Style.Triggers> 
           <DataTrigger Binding="{Binding Tag, RelativeSource={RelativeSource Self}}" Value="True"> 
            <Setter Property="Background" Value="Transparent"/> 
            <Setter Property="Padding" Value="0,0,5,5"/> 
            <Setter Property="Effect"> 
             <Setter.Value> 
              <DropShadowEffect BlurRadius="4" Opacity="0.8" ShadowDepth="1"/> 
             </Setter.Value> 
            </Setter> 
           </DataTrigger> 
          </Style.Triggers> 
         </Style> 
        </Border.Style> 
       </Border> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

Hope this helps. Dans la minutie habituelle de MS, les brosses dans le style par défaut ne sont pas trouvées. :)

+0

Ha ha !: * J'ai trouvé le moyen facile d'obtenir le modèle ContextMenu dans Blend * - cela semble être le moyen le plus simple! – bgmCoder

+3

Semble ne pas être un XAML complet. Où est la définition de 'ContextMenuControlTemplate1'? –

2

Essayez ceci: (Placez ce code dans votre partie Ressources de votre XAML) Ceci devrait supprimer la bande d'icônes du menu contextuel.

<Style TargetType="{x:Type ContextMenu}"> 
    <Setter Property="OverridesDefaultStyle" Value="True" /> 
    <Setter Property="SnapsToDevicePixels" Value="True" /> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type ContextMenu}"> 
       <Border BorderThickness="1" CornerRadius="4" BorderBrush="Black" x:Name="Border" Background="White"> 
        <StackPanel ClipToBounds="True" Orientation="Vertical" IsItemsHost="True" /> 
       </Border> 
       <ControlTemplate.Triggers> 
        <Trigger Property="IsMouseOver" Value="true"> 
         <Setter TargetName="Border" Property="Background" Value="White" /> 
        </Trigger> 
       </ControlTemplate.Triggers> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style>