2012-05-21 10 views
5

を制御を与える:マウスホイールを使用してWPFネストされたScrollviewers - これは私のコントロールツリーがどのように見えるかであるバック親scollviewerへ

<window> 
<scrollviewer> 
    <expander> 
    <scrollviewer> 
    <grid> 
    </grid> 
    </scrollviewer> 
    </expander> 
    <expander> 
    <scrollviewer> 
    <grid> 
    </grid> 
    </scrollviewer> 
    </expander> 
</scrollviewer> 
</window> 

、コントロールが自動的に子ScrollViewerのに親から渡されますが、私はにスクロールしたときに子スクロールビューアーの最後のコントロールは親スコアービューアーに返されません。これをどのように達成するのですか?

エクスパンダ、グリッド、スクロールビューアが動的に生成されます。

+0

[この質問](http://stackoverflow.com/q/14348517/1925996)の回答も参照してください。 – piedar

答えて

10

私のアプリケーションでも同様の問題が発生します。私はイベントをキャッチして彼の親を渡すことになるdepencyのプロパティによってそれを修正します。これは、スクロールを持つコントロールに適用できます。しかし、私にとっては、スクロールの終わりに親に送っていれば、私は検証する必要はありませんでした。 OnValueChangedメソッドで、スクロールが最後にある場合、または親に送信する場合は先頭に検証を追加するだけです。

using System.Windows.Controls; 

public static class SendMouseWheelToParent 
{ 
    public static readonly DependencyProperty ScrollProperty 
    = DependencyProperty.RegisterAttached("IsSendingMouseWheelEventToParent", 
     typeof(bool), 
     typeof(SendMouseWheelToParent), 
     new FrameworkPropertyMetadata(OnValueChanged)); 

    /// <summary> 
    /// Gets the IsSendingMouseWheelEventToParent for a given <see cref="TextBox"/>. 
    /// </summary> 
    /// <param name="control"> 
    /// The <see cref="TextBox"/> whose IsSendingMouseWheelEventToParent is to be retrieved. 
    /// </param> 
    /// <returns> 
    /// The IsSendingMouseWheelEventToParent, or <see langword="null"/> 
    /// if no IsSendingMouseWheelEventToParent has been set. 
    /// </returns> 
    public static bool? GetIsSendingMouseWheelEventToParent(Control control) 
    { 
     if (control == null) 
      throw new ArgumentNullException(""); 

     return control.GetValue(ScrollProperty) as bool?; 
    } 

    /// <summary> 
    /// Sets the IsSendingMouseWheelEventToParent for a given <see cref="TextBox"/>. 
    /// </summary> 
    /// <param name="control"> 
    /// The <see cref="TextBox"/> whose IsSendingMouseWheelEventToParent is to be set. 
    /// </param> 
    /// <param name="IsSendingMouseWheelEventToParent"> 
    /// The IsSendingMouseWheelEventToParent to set, or <see langword="null"/> 
    /// to remove any existing IsSendingMouseWheelEventToParent from <paramref name="control"/>. 
    /// </param> 
    public static void SetIsSendingMouseWheelEventToParent(Control control, bool? sendToParent) 
    { 
     if (control == null) 
      throw new ArgumentNullException(""); 

     control.SetValue(ScrollProperty, sendToParent); 
    } 

    private static void OnValueChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e) 
    { 
     var scrollViewer = dependencyObject as Control; 
     bool? IsSendingMouseWheelEventToParent = e.NewValue as bool?; 
     scrollViewer.PreviewMouseWheel -= scrollViewer_PreviewMouseWheel; 

     if (IsSendingMouseWheelEventToParent != null && IsSendingMouseWheelEventToParent != false) 
     { 
     scrollViewer.SetValue(ScrollProperty, IsSendingMouseWheelEventToParent); 
     scrollViewer.PreviewMouseWheel += scrollViewer_PreviewMouseWheel; 
     } 
    } 


    private static void scrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e) 
    { 
     var scrollview = sender as Control; 

     var eventArg = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta); 
     eventArg.RoutedEvent = UIElement.MouseWheelEvent; 
     eventArg.Source = sender; 
     var parent = scrollview.Parent as UIElement; 
     parent.RaiseEvent(eventArg); 
    } 
} 
+0

論理ツリー親 'scrollView.Parent as UIElement;'の代わりに、ビジュアルツリーの親 'VisualTreeHelper.GetParent(scrollview)をUIElement;として使うことをお勧めしますが、私は失敗した構造を覚えていません論理的な親と一緒に。 – grek40

関連する問題