2010-04-18 8 views
18

Ich erstelle eine WPF-App mit dem MVVM-Designmuster, und ich versuche, das TabItem-Steuerelement so zu erweitern, dass es die Registerkarte schließt, wenn der Benutzer auf die mittlere Maustaste klickt. Ich versuche, dies mit InputBindings zu erreichen, und es funktioniert sehr gut, bis ich versuche, es in einem Stil zu definieren. Ich habe gelernt, dass Sie InputBindings nur dann zu einem Stil hinzufügen können, wenn Sie ihn mit DependencyProperty anhängen. Also ich folgte diesem ähnlichen Beitrag here... und es funktioniert ... fast. Ich kann eine Registerkarte mit der mittleren Maustaste schließen, aber sie funktioniert nicht auf einer der anderen Registerkarten (alle Registerkarten werden zur Laufzeit hinzugefügt und übernehmen den gleichen Stil).Definieren von InputBindings innerhalb eines Styles

Also brauche ich etwas Hilfe. Warum sollte das nur beim ersten Mal funktionieren und nicht danach? Natürlich könnte ich ein benutzerdefiniertes Steuerelement erstellen, das von einem TabItem erbt und es funktionieren lässt, aber ich möchte das herausfinden, da ich sehe, dass es in meinen Projekten erweitert wird. Ich bin kein Experte für DependencyProperties, also bitte hilf mir. Vielen Dank!

Stil:

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

Klasse

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

Ich bin auf das genaue oben beschriebene Problem sogar mit dem von Daniel vorgeschlagenen Code gestoßen. Es scheint, dass etwas sehr merkwürdig ist, wenn Sie die Attach-Klasse oben verwenden, besonders in einem Stil. Ich habe festgestellt, dass DataContext "manchmal" null war, wenn die InputBindings hinzugefügt wurden. Wenn die Bindung passierte, konnte es die Befehle nicht finden. Ich habe nie eine Lösung gefunden, aber ich habe die Bindungen wie in der Antwort unten dupliziert. – Asheh

Antwort

14

Es macht nichts, ich es selbst herausgefunden. Am Ende habe ich nicht einmal die Attach-Klasse verwendet, sondern stattdessen InputBindings auf der ControlTemplate für das TabItem (was ein Border ist), also sah es ungefähr so ​​aus ... Ich weiß nicht, warum ich nicht gedacht habe von diesem in erster Linie .. :)

<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

Ich mag diese Lösung nicht, weil ich jedes von mir erstellte Template überschreiben muss ... –

14

Ihre Klasse "Attach" hat gut für mich gearbeitet! Wenn jemand braucht, ist der Trick, wie diese Verwendung Stil, mit dem x: Gemeinsames Modifikator:

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

Dank!