2009-03-13 18 views
9

Estoy intentando modificar el estilo predeterminado de ContextMenu en WPF.Estilo ContextMenu predeterminado - WPF

Normalmente, puede crear una copia del valor predeterminado en Expression Blend utilizando la opción de Editar partes de control (Plantilla)> Editar una copia. Sin embargo, no puedo encontrar la forma de hacerlo con un ContextMenu. ¿Alguna idea de cómo puedo obtener el estilo predeterminado para modificar?

Estoy tratando de desactivar el lado izquierdo del menú contextual donde los iconos se muestran normalmente.

Gracias!

Actualización: Quizás no estaba claro sobre la eliminación de los iconos. Por ejemplo, si tiene un menú contextual sin iconos, todo el lado izquierdo del menú es espacio desperdiciado. Me gustaría modificar el estilo predeterminado del fondo del menú contextual para eliminar esto. Simplemente no sé cómo acceder a este estilo predeterminado.

+0

Luke, ¿resolvió este problema? Estoy un poco confundido por todas esas diferentes ideas a continuación. Gracias por cualquier pista! –

+0

Sí, utilicé la respuesta a continuación para obtener la plantilla y la modifiqué desde allí. – Luke

Respuesta

10

Para las plantillas y estilos que no son accesibles a través de la interfaz de expresión (como la plantilla ContextMenu), puede utilizar el siguiente código para extraer la plantilla:

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) 

O en C#

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

Tenga en cuenta que para obtener una plantilla en un ContextMenu, al menos debe agregar un elemento de menú a su colección de elementos. De lo contrario, ContextMenu.Template es nulo. –

+0

Me encanta Stack Overflow. Muchas gracias por estas respuestas, exactamente lo que necesitaba también. – scobi

2

En realidad, el espacio no es parte del ContextMenu, es parte de MenuItem. Así que simplemente arrastre un MenuItem a su ventana en la expresión blend y cree una copia del control. Esperamos que su declaración ContextMenu es el siguiente

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

Y dentro de su Menultem ControlTemplate se puede ver el espacio como abajo. Por lo tanto, elimine el ícono y la primera columna de la cuadrícula que marqué en la captura de pantalla.

alt text

+0

Bueno, eso me da el estilo predeterminado para MenuItem, sin embargo, no me da el estilo ContextMenu. Expression Blend no me permitirá agregar un ContextMenu a la ventana. – Luke

+0

Muestra un error, "ContextMenu no puede tener el elemento primario lógico o visual" si agrego el ContextMenu a la ventana. – Luke

+0

Sí, también hay estilos dentro del ContextMenu para el menú del lado izquierdo que deben eliminarse. Son los estilos ContextMenu a los que no puedo acceder usando la interfaz Expression. He publicado una solución a continuación para extraer la plantilla usando el código. – Luke

0

El espacio extra en la parte izquierda se debe a la pequeña marca de verificación que aparece cuando se establece IsCheckable y IsChecked a true en MenuItem.

La marca de verificación está en la plantilla para MenuItem, por lo que si edita eso, puede sacarlo.

+0

La propiedad 'IsCheckable' afecta la interacción del usuario con un elemento de menú, no si el área de verificación/icono se muestra en el menú. De hecho, el valor predeterminado ya es 'False'. Al establecerlo en 'Verdadero', simplemente aparece la marca de verificación para alternar automáticamente cada vez que el usuario selecciona ese elemento del menú. –

7

he encontrado la manera fácil de hacer que la plantilla ContextMenu Blend:

  1. he añadido un ContextMenu a un butto n con algunos elementos de menú.
  2. En "Miscellaneous" en el panel de propiedades, hay un elemento agrupado para ContextMenu.
  3. Abrir esto. Encontrarás las propiedades de Estilo y Plantilla usuales.
  4. Haga clic en el cuadrado para el menú emergente y seleccione Convertir en Nuevo recurso ...

Eso es todo. Elija dónde desea que se coloque la plantilla o el estilo, y listo.

Aquí está el margen de beneficio que tenía:

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

Y el estilo/plantilla que tengo:

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

Espero que esto ayude. En la meticulosidad habitual de MS, no se encuentran los pinceles en el estilo predeterminado. :)

+0

¡Ja, ja !: * Encontré la manera fácil de obtener la plantilla ContextMenu en Blend * - ¡eso parece ser la manera más fácil! – bgmCoder

+3

Parece que no es un XAML completo. ¿Dónde está definiendo 'ContextMenuControlTemplate1'? –

2

Pruebe esto: (Ponga este código en su parte de Recursos de su XAML) Esto debería eliminar la franja de icono del menú contextual.

<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> 
Cuestiones relacionadas