2011-12-03 18 views
6

काम नहीं कर WPF में मैं निम्नलिखित XAML मिल गया है:एक स्पर्श अंतरफलक में स्लाइडर ScrollViewer ठीक से

<ScrollViewer Canvas.Left="2266" Canvas.Top="428" Height="378" Name="scrollViewer1" Width="728" PanningMode="VerticalOnly" PanningRatio="2"> 
    <Canvas Height="1732.593" Width="507.667"> 
     <Slider Height="40.668" x:Name="slider1" Width="507.667" Style="{DynamicResource SliderStyle1}" Canvas.Left="15" Canvas.Top="150" /> 
     </Slider> 
    </Canvas> 
</ScrollViewer> 

यह एक ScrollViewer एक स्लाइडर युक्त है। मैं टच-स्क्रीन पर निम्न का उपयोग कर रहा हूं, और मैं लंबवत स्क्रॉलव्यूयर को स्क्रॉल करने के लिए भी पैनिंग का उपयोग कर रहा हूं। जब PanningMode = "वर्टिकलऑनली" सेट किया गया है, स्लाइडर काम करना बंद कर देता है!

मुझे लगता है कि स्कॉलवियर टच \ स्लाइड ईवेंट का उपभोग कर रहा है और स्लाइडर से पहले इसे संभालने वाला है (लेकिन मुझे लगता है कि मैं इस मोर्चे पर गलत हूं)।

क्या इसके लिए कोई कामकाज है?

उत्तर

10

मैंने अभी इस मुद्दे को हमारे ऐप में हल किया है।

क्या हो रहा है यह है कि स्क्रॉलव्यूयर टचडिवाइस को अपने पूर्वावलोकन टचमोव हैंडलर में कैप्चर करता है, जो अन्य नियंत्रणों से टचडिवाइस को "चुराता है" और उन्हें किसी भी पूर्वावलोकन टचमोव या टचमोव ईवेंट प्राप्त करने से रोकता है।

इस के आसपास काम करने के लिए, आपको कस्टम थंब नियंत्रण को लागू करने की आवश्यकता है जो पूर्वावलोकन टचडाउन ईवेंट में टचडिवाइस को कैप्चर करता है और पूर्वावलोकन टचअप ईवेंट होने तक इसका संदर्भ संग्रहीत करता है। फिर नियंत्रण उचित होने पर, लॉस्ट टच कैप्चर हैंडलर में कैप्चर बैक को "चोरी" कर सकता है।

public class CustomThumb : Thumb 
{ 
    private TouchDevice currentDevice = null; 

    protected override void OnPreviewTouchDown(TouchEventArgs e) 
    { 
     // Release any previous capture 
     ReleaseCurrentDevice(); 
     // Capture the new touch 
     CaptureCurrentDevice(e); 
    } 

    protected override void OnPreviewTouchUp(TouchEventArgs e) 
    { 
     ReleaseCurrentDevice(); 
    } 

    protected override void OnLostTouchCapture(TouchEventArgs e) 
    { 
     // Only re-capture if the reference is not null 
     // This way we avoid re-capturing after calling ReleaseCurrentDevice() 
     if (currentDevice != null) 
     { 
      CaptureCurrentDevice(e); 
     } 
    } 

    private void ReleaseCurrentDevice() 
    { 
     if (currentDevice != null) 
     { 
      // Set the reference to null so that we don't re-capture in the OnLostTouchCapture() method 
      var temp = currentDevice; 
      currentDevice = null; 
      ReleaseTouchCapture(temp); 
     } 
    } 

    private void CaptureCurrentDevice(TouchEventArgs e) 
    { 
     bool gotTouch = CaptureTouch(e.TouchDevice); 
     if (gotTouch) 
     { 
      currentDevice = e.TouchDevice; 
     } 
    } 
} 

तो फिर तुम स्लाइडर CustomThumb बजाय डिफ़ॉल्ट अंगूठे नियंत्रण का उपयोग करने के लिए फिर से टेम्पलेट की आवश्यकता होगी: यहाँ कुछ संक्षिप्त कोड है।

+2

मैंने अभी तक इस दृष्टिकोण का परीक्षण नहीं किया है, लेकिन यह पर्याप्त मान्य दिखता है। मैं इसे उत्तर के रूप में चुनूंगा। जिस तरह से मैंने अपने सभी मुद्दों को हल किया, वह माइक्रोसॉफ्ट सर्फेस 2.0 एसडीके http://www.microsoft.com/download/en/details.aspx?id=26716 का उपयोग करके और अपनी लाइब्रेरी से स्क्रॉलव्यूयर का उपयोग कर रहा था (जो उपर्युक्त सभी समस्याओं को संभालता है)। – Bassem

+1

यह समाधान मेरे लिए काम किया। यह बहुत सुविधाजनक था क्योंकि मैंने पहले से ही स्लाइडर को एक कस्टम अंगूठे का उपयोग करने के लिए आकार/आकार के साथ स्पर्श करने के लिए अधिक उपयुक्त बनाया था। – tgr42

+0

प्रदान किया गया दृष्टिकोण एक आकर्षण की तरह काम करता है! माइक्रोसॉफ्ट सर्फेस 2.0 एसडीके को हटाने के लिए मुझे समस्या का सामना करना पड़ा (मेरे लिए बहिष्कृत)। – SSchuette

2

मैं एक समान मुद्दे के साथ strugled। कामकाज यह था (दूसरों में से कोई भी मेरे लिए काम नहीं करता था): मैंने एक कस्टम थंब बनाया, और फिर मैंने इसे xaml में स्क्रॉलबार शैली के अंदर PART_Track के अंगूठे के रूप में उपयोग किया।

public class DragableThumb : Thumb 
{ 
    double m_originalOffset; 
    double m_originalDistance; 
    int m_touchID; 

    /// <summary> 
    /// Get the parent scrollviewer, if any 
    /// </summary> 
    /// <returns>Scroll viewer or null</returns> 
    ScrollViewer GetScrollViewer() 
    { 
     if (TemplatedParent is ScrollBar && ((ScrollBar)TemplatedParent).TemplatedParent is ScrollViewer) 
     { 
      return ((ScrollViewer)((ScrollBar)TemplatedParent).TemplatedParent); 
     } 

     return null; 
    } 

    /// <summary> 
    /// Begin thumb drag 
    /// </summary> 
    /// <param name="e">Event arguments</param> 
    protected override void OnTouchDown(TouchEventArgs e) 
    { 
     ScrollViewer scrollViewer; 

     base.OnTouchDown(e); 

     m_touchID = e.TouchDevice.Id; 

     if ((scrollViewer = GetScrollViewer()) != null) 
     { 
      m_originalOffset = scrollViewer.HorizontalOffset; 
      m_originalDistance = e.GetTouchPoint(scrollViewer).Position.X; 
     } 
    } 

    /// <summary> 
    /// Handle thumb delta 
    /// </summary> 
    /// <param name="e">Event arguments</param> 
    protected override void OnTouchMove(TouchEventArgs e) 
    { 
     ScrollViewer scrollViewer; 
     double actualDistance; 

     base.OnTouchMove(e); 

     if ((scrollViewer = GetScrollViewer()) != null && m_touchID == e.TouchDevice.Id) 
     { 
      actualDistance = e.GetTouchPoint(scrollViewer).Position.X; 
      scrollViewer.ScrollToHorizontalOffset(m_originalOffset + (actualDistance - m_originalDistance) * scrollViewer.ExtentWidth/scrollViewer.ActualWidth); 
     } 
    } 
} 
+0

धन्यवाद, यह मुझे मेरे मुद्दे के लिए सही रास्ते पर सेट किया गया है। –

0

निम्नलिखित मेरे लिए काम किया। मैंने काम करने के लिए लंबे समय तक चारों ओर खोज की। मैंने इसे How to make WPF Slider Thumb follow cursor from any point से स्पर्श के लिए अनुकूलित किया। यह एक बहुत ही सरल फिक्स है और आपको एक कस्टम स्लाइडर/अंगूठे नियंत्रण बनाने से बचने की अनुमति देता है।

<Slider TouchMove="OnTouchMove" IsMoveToPointEnabled="True"/> 

IsMoveToPointEnable को काम करने के लिए इसे सही पर सेट किया जाना चाहिए।

private void Slider_OnTouchMove(object sender, TouchEventArgs e) 
{ 
    Slider slider = (Slider)sender;   
    TouchPoint point = e.GetTouchPoint (slider); 
    double d = 1.0/slider.ActualWidth * point.Position.X; 
    int p = int(slider.Maximum * d); 
    slider.Value = p; 
} 
0

यह अच्छा और सरल है और मेरे लिए काम किया - हालांकि यह एक सामान्य समारोह में लपेटकर और भी स्लाइडर न्यूनतम मूल्य को संभालने के लिए के रूप में यह शून्य नहीं हो सकता है विस्तार के लायक है। हालांकि क्या करना है दर्द करना है। डब्ल्यूपीएफ के बारे में बहुत सी चीजें हैं जो शांत हैं, लेकिन इतनी सारी सरल चीजों को अतिरिक्त कदमों की आवश्यकता होती है जो वास्तव में उत्पादकता के लिए हानिकारक हो सकती हैं।