2013-02-19 44 views
2

我正在開發一個支持觸摸的設備的WPF。我面臨一個奇怪的問題。我的XAML結構是操作事件和平移模式

<ScrollViewer> 
    <StackPanel orientation="Horizontal"> 
     <!-- Control goes here --> 
     </StackPanel> 
    <ScrollViewer> 

現在

  1. 將啓用滾動觸摸我必須設置PannigModeHorizo​​ntalOnly
  2. 要接收操縱事件我必須設置PannigMode

問題是我必須同時具有這兩個功能。

有什麼解決辦法,以便的ScrollViewer滾動觸摸,也是在ManipulationCompleted事件觸發。

請幫忙。

+0

有人請做響應。 – Gulshan 2013-02-20 07:31:55

回答

1

我有同樣的問題。您至少有兩種選擇

  • 使用MS表面工具包
  • 修復的ScrollViewer

我選擇了第二個。只需在Generic.xaml中創建一個從ScrollViewer繼承的自定義控件,只需要放一個<ContentPresenter />即可,僅此而已。 真正的工作是在代碼背後,但也沒有那麼複雜。我必須檢查用戶是否觸摸了按鈕或者只是想滾動。訣竅是檢查觸摸點上的內容,並打開/關閉平移模式。

這裏是代碼:

namespace Demo.Controls 
{ 
    public class ScrollViewerWithTouch : ScrollViewer 
    { 
    private PanningMode panningMode; 


    private bool panningModeSet; 

     static ScrollViewerWithTouch() 
     { 
     DefaultStyleKeyProperty.OverrideMetadata(typeof(ScrollViewerWithTouch), new FrameworkPropertyMetadata(typeof(ScrollViewerWithTouch))); 
     } 

     protected override void OnManipulationCompleted(ManipulationCompletedEventArgs e) 
     { 
     base.OnManipulationCompleted(e); 

     // set it back 
     this.PanningMode = this.panningMode; 
     } 

     protected override void OnManipulationStarted(ManipulationStartedEventArgs e) 
     { 
     // figure out what has the user touched 
     var result = VisualTreeHelper.HitTest(this, e.ManipulationOrigin); 
     if (result != null && result.VisualHit != null) 
     { 
      var hasButtonParent = this.HasButtonParent(result.VisualHit); 

      // if user touched a button then turn off panning mode, let style bubble down, in other case let it scroll 
      this.PanningMode = hasButtonParent ? PanningMode.None : this.panningMode; 
     } 
     base.OnManipulationStarted(e); 
     } 

     protected override void OnTouchDown(TouchEventArgs e) 
     { 
     // store panning mode or set it back to it's original state. OnManipulationCompleted does not do it every time, so we need to set it once more. 
     if (this.panningModeSet == false) 
     { 
      this.panningMode = this.PanningMode; 
      this.panningModeSet = true; 
     } 
     else 
     { 
      this.PanningMode = this.panningMode; 
     } 

     base.OnTouchDown(e);   
     } 

     private bool HasButtonParent(DependencyObject obj) 
     { 
     var parent = VisualTreeHelper.GetParent(obj); 

     if ((parent != null) && (parent is ButtonBase) == false) 
     { 
      return HasButtonParent(parent); 
     } 

     return parent != null; 
     } 
    } 
}