2010-04-18 15 views
18

MVVM tasarım desenini kullanarak bir WPF uygulaması oluşturuyorum ve kullanıcı, farenin orta düğmesini tıkladığında sekmeyi kapatması için TabItem denetimini genişletmeye çalışıyorum. Bunu InputBindings kullanarak yapmaya çalışıyorum ve bir stil içinde tanımlamaya çalışana kadar çok iyi çalışıyor. Bir DependencyProperty kullanarak eklemediğiniz sürece, InputBindings'i bir stile ekleyemeyeceğinizi öğrendim. Bu yüzden benzer bir yazıyı takip ettim here... ve hemen hemen çalışıyor. Orta fare düğmesini kullanarak bir sekmeyi kapatabilirim, ancak diğer sekmelerden herhangi birinde çalışmaz (tüm sekmeler çalışma zamanında eklenir ve aynı stili miras alır).Bir Stil İçindeki InputBindings'i Tanımlama

Bazı yardıma ihtiyacım var. Neden bu sadece ilk kez çalışıyor, sonra değil mi? Tabii ki bir TabItem'den miras alan ve çalışmasını sağlayan özel bir denetim oluşturabilirim, ancak bunu projemde genişletildiğini görebildiğim için anlamaya çalışıyorum. DependencyProperties konusunda uzman değilim, lütfen bana yardımcı olun. Teşekkürler!

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> 

Sınıf

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

Daniel'in önerdiği kodda bile yukarıda açıklanan kesin problemi araştırdım. Yukarıdaki gibi Attach sınıfını kullanırken, özellikle de bir stilde çok garip bir şey var gibi görünüyor. Ben InputBindings eklendiğinde DataContext null "bazen" olduğunu buldum, bu yüzden bağlama gerçekleştiğinde komutları bulamadı. Asla bir çözüm bulamadım, ancak aşağıdaki yanıtta olduğu gibi bağlayıcıları çoğaltmaya başladım. – Asheh

cevap

14

kendim anladım, boşver. Yukarıdaki Attach sınıfını bile kullanamadım ... yerine InputBindings'i ControlTemplate üzerinde TabItem için kullandım (bir Border), bu yüzden böyle bir şeye benziyordu ... Neden düşünmedim bilmiyorum bunun için ilk etapta .. :)

<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

Bu çözümü sevmiyorum çünkü yarattığım herhangi bir Şablonu geçersiz kılmam gerekiyor ... –

14

Sınıfınız “Attach” benim için iyi çalıştı! Paylaşılan değiştirici:: herkes ihtiyacı varsa , hile böyle kullanılması tarzı x ile olan

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

teşekkürler!