2010-02-22 21 views
8

Bir WPF Popup (örneğin ButtonClick aracılığıyla) açtığınız durumu hayal edin. ListBox, bazı öğelerle birlikte Popup ürününüzde doğrudan yer aldığından, kaydırma yapabilmeniz gerekir. Bunun sizin için Custom Control olduğunu ve ScrollViewer adresinde olduğunu düşünün.WPF Kaydırma ana denetimini denetle

Eğer farenizle dışarıda Popup yüzeyinden hareket edip ilerleyin ve ne olur? Yukarı ve aşağı kaydırıyorsunuz ama Popup açıldı! Ve sorun bu.

Sorun, Denetimin içinden, VisualTree'deki diğer bazı Bilinmeyen Ebeveyn Denetimlerinin kaydırılmaya başlanmasının nasıl algılanacağıdır. ve art arda IsDropDownOpen = false mu ayarlandı?

+0

Aynı soru ve sorun var. Izgaramı kaydırıyorum ve özel işlemlerle açılan pencerem aynı yerde kalıyor! Izgara ile açılan pencereyi kaydırmam gerek! – Evgeny

cevap

10

ScrollViewer içinde bulunan öğelerle kullanmak için bir tetikleyici yazabiliriz.

<Grid> 
    <ScrollViewer VerticalAlignment="Top" Height="200"> 
     <StackPanel HorizontalAlignment="Left"> 
      <Button Name="button" Content="Open"> 
       <i:Interaction.Triggers> 
        <i:EventTrigger EventName="Click"> 
         <ei:ChangePropertyAction TargetObject="{Binding ElementName=popup}" PropertyName="IsOpen" Value="True"/> 
        </i:EventTrigger> 
        <local:ScrollTrigger> 
         <ei:ChangePropertyAction TargetObject="{Binding ElementName=popup}" PropertyName="IsOpen" Value="False"/> 
        </local:ScrollTrigger> 
       </i:Interaction.Triggers> 
      </Button> 
      <Popup Name="popup" PlacementTarget="{Binding ElementName=button}"> 
       <TextBlock Background="White" Text="Sample text"/> 
      </Popup> 
      <Rectangle Width="100" Height="100" Fill="Red"/> 
      <Rectangle Width="100" Height="100" Fill="Green"/> 
      <Rectangle Width="100" Height="100" Fill="Blue"/> 
      <Rectangle Width="100" Height="100" Fill="Yellow"/> 
     </StackPanel> 
    </ScrollViewer> 
</Grid> 

Biz Popup ve ScrollTrigger eylemler yangın ve sonra biz pop-up'ı kapatabilirsiniz neden ScrollViewer herhangi ebeveyn herhangi kaydırma açan bir düğme vardır: İşte tam bir örnek uygulamasıdır. Tetikleyicinin Popup'a değil Button'a eklendiğini unutmayın. Görsel ağaçtaki yakındaki herhangi bir elemanı kullanabiliriz. Ayrıca, Popup'u açmak için başka bir tetikleyici kullandığımızı, ancak nasıl açıldığının orijinal soru için önemli olmadığını unutmayın. İşte

ScrollTrigger geçerli:

class ScrollTrigger : TriggerBase<FrameworkElement> 
{ 
    protected override void OnAttached() 
    { 
     AssociatedObject.Loaded += new RoutedEventHandler(AssociatedObject_Loaded); 
    } 

    void AssociatedObject_Loaded(object sender, RoutedEventArgs e) 
    { 
     foreach (var scrollViewer in GetScrollViewers()) 
      scrollViewer.ScrollChanged += new ScrollChangedEventHandler(scrollViewer_ScrollChanged); 
    } 

    void scrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e) 
    { 
     InvokeActions(e.OriginalSource); 
    } 

    IEnumerable<ScrollViewer> GetScrollViewers() 
    { 
     for (DependencyObject element = AssociatedObject; element != null; element = VisualTreeHelper.GetParent(element)) 
      if (element is ScrollViewer) yield return element as ScrollViewer; 
    } 
} 

ScrollTrigger çok basittir, sadece tüm üst ScrollChanged olaylara verdiği ve işlemleri içerdiği ateşler. Örnekte Popup'u kapatmak için ChangePropertyAction kullanıyoruz. Eğer davranışları ile aşina değilseniz

, Expression Blend 4 SDK yüklemek ve bu ad alanları ekleyin:

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" 

ve projenize System.Windows.Interactivity ve Microsoft.Expression.Interactions ekleyin.

1

Denetimlerinizin nasıl olduğunu tam olarak açıklamıyorum, ancak Focus olayındaki bir denetimin açılmasını/kapatılmasını temel almıyor musunuz? Ve odağı kaybederse, pop-up'ı kapatmak için? Belki de yanlış anlıyorum, kod snippet'i gönderebilir misiniz? Daniel