2010-04-18 7 views
18

Estoy creando una aplicación WPF usando el patrón de diseño MVVM, y estoy tratando de extender el control TabItem para que cierre la pestaña cuando el usuario haga clic en el botón central del mouse. Estoy tratando de lograr esto usando InputBindings, y funciona muy bien hasta que trato de definirlo dentro de un estilo. Aprendí que no puedes agregar InputBindings a un estilo a menos que lo conectes con DependencyProperty. Así que seguí esta publicación similar here... y funciona ... casi. Puedo cerrar una pestaña usando el botón central del mouse, pero no funcionará en ninguna de las otras pestañas (todas las pestañas se agregan en el tiempo de ejecución y heredan el mismo estilo).Definición de uniones de entrada dentro de un estilo

Así que necesito ayuda. ¿Por qué esto solo estaría funcionando la primera vez, y no después? Obviamente, podría crear un control personalizado que herede de un TabItem y hacerlo funcionar, pero me gustaría resolverlo ya que puedo ver que esto se amplía en mis proyectos. No soy un experto en DependencyProperties, así que por favor ayúdenme. ¡Gracias!

Estilo:

<Style TargetType="{x:Type TabItem}"> 
    <Setter Property="w:Attach.InputBindings"> 
     <Setter.Value> 
      <InputBindingCollection> 
       <MouseBinding MouseAction="MiddleClick" 
           Command="{Binding CloseCommand}"/> 
      </InputBindingCollection> 
     </Setter.Value> 
    </Setter> 
    ... 
</Style> 

Clase

public class Attach 
{ 
    public static readonly DependencyProperty InputBindingsProperty = 
     DependencyProperty.RegisterAttached("InputBindings", typeof(InputBindingCollection), typeof(Attach), 
     new FrameworkPropertyMetadata(new InputBindingCollection(), 
     (sender, e) => 
     { 
      var element = sender as UIElement; 
      if (element == null) return; 
      element.InputBindings.Clear(); 
      element.InputBindings.AddRange((InputBindingCollection)e.NewValue); 
     })); 

    public static InputBindingCollection GetInputBindings(UIElement element) 
    { 
     return (InputBindingCollection)element.GetValue(InputBindingsProperty); 
    } 

    public static void SetInputBindings(UIElement element, InputBindingCollection inputBindings) 
    { 
     element.SetValue(InputBindingsProperty, inputBindings); 
    } 
} 
+0

Me he encontrado con el problema exacto descrito anteriormente, incluso con el código sugerido por Daniel. Parece que hay algo muy extraño cuando se usa la clase Attach anterior, especialmente en un estilo. Descubrí que DataContext era nulo "a veces" cuando se agregaban los InputBindings, por lo que, cuando ocurría el enlace, no podía localizar los comandos. Nunca encontré una solución pero terminé duplicando los enlaces como en la respuesta a continuación. – Asheh

Respuesta

14

No importa, lo he descubierto a mí mismo. Terminé sin usar la clase Attach anterior ... en su lugar utilicé InputBindings en ControlTemplate para TabItem (que es un borde), por lo que se veía algo así ... No sé por qué no pensé de esta en el primer lugar .. :)

<ControlTemplate TargetType="{x:Type TabItem}"> 
    <Grid SnapsToDevicePixels="true"> 
     <Border x:Name="Bd" ...> 
      <DockPanel> 
       ... 
      </DockPanel> 
      <Border.InputBindings> 
       <MouseBinding MouseAction="MiddleClick" 
           Command="{Binding CloseCommand}"/> 
      </Border.InputBindings> 
     </Border> 
    </Grid> 
    ... 
</ControlTemplate> 
+0

No me gusta esta solución porque tengo que anular cualquier Plantilla que creé ... –

14

Su clase "Adjuntar" funcionó bien para mí! Si alguien necesita, el truco está en uso el estilo de este tipo, con la x: compartido modificador:

<InputBindingCollection x:Key="inputCollection" x:Shared="False"> 
     <KeyBinding Key="Del" Command="{Binding DeleteItemCommand}"/> 
</InputBindingCollection> 

<Style TargetType="{x:Type TabItem}"> 
    <Setter Property="w:Attach.InputBindings" Value="{StaticResource inputCollection}" /> 
    ... 
</Style> 

Gracias!

Cuestiones relacionadas