2009-05-18 16 views
6

मैं ViewingMode = "स्क्रॉल" के साथ FlowDocumentReader में फ़्लो डॉक्यूमेंट प्रदर्शित कर रहा हूं। अगर मैं अपने माउस पर पहिया का उपयोग करता हूं, तो दस्तावेज़ बहुत धीरे-धीरे स्क्रॉल करता है। मैं स्क्रॉल चरण को बढ़ाना चाहता हूं।फ़्लो डॉक्यूमेंटर रीडर की स्क्रॉल वृद्धि समायोजित करें जब दृश्यमान स्क्रॉल करने के लिए सेट करें?

  1. मैंने नियंत्रण कक्ष में अपने माउस की स्क्रॉल सेटिंग बदलने की कोशिश की है, लेकिन इसका कोई प्रभाव नहीं पड़ता है। मुझे लगता है कि WPF FlowDocumentScrollViewer के लिए उस सेटिंग को अनदेखा करता है।

  2. मैंने फ्लो डॉक्यूमेंट और फ़्लो डॉक्यूमेंट रीडर पर एक स्क्रॉल ईवेंट जोड़ा है, लेकिन जब मैं माउस व्हील का उपयोग करता हूं तो यह आग नहीं होता है।

  3. मैं FlowDocumentReader पर एक लोडेड घटना जोड़ दिया है, ScrollViewer वंशज है, स्क्रॉल दर्शक के खाके से स्क्रॉलपट्टी ("PART_VerticalScrollBar") पाया जाता है और SmallChange & LargeChange गुण समायोजित। इसका कोई प्रभाव नहीं पड़ा।

किसी के पास कोई विचार है?

+0

यदि आपके उत्तर पर आपको जो ट्वीक करना था, वह मानक गति के लिए '/ 6' था, तो मुझे एक और सवाल का जवाब देते हुए इसे करने का बेहतर तरीका पता चला। यदि आप इसके बजाय SystemInformation.MouseWheelScrollLines/3 (वर्तमान कंप्यूटर सेटिंग्स/डिफ़ॉल्ट) से गुणा करते हैं तो इसे स्थिर गति के बजाय उपयोगकर्ताओं की माउस सेटिंग्स के आधार पर काम करना चाहिए। – rmoore

उत्तर

19

हम एक नियंत्रण के माउसव्हील घटना में इस संशोधित कर सकते हैं, Sohnee तरह sugested, लेकिन तब यह सिर्फ एक विशेष मामले के लिए हल किया जा चाहते हैं, और आप FlowDocumentReader, के लिए उपयोग किया होगा जो आपके usinging अगर कुछ एमवीवीएम की तरह, आप नहीं करेंगे। इसके बजाए, हम एक संलग्न संपत्ति बना सकते हैं जिसे हम किसी भी तत्व को स्क्रॉलव्यूयर के साथ सेट कर सकते हैं। हमारी संलग्न संपत्ति को परिभाषित करते समय, हम एक संपत्तिChanged कॉलबैक भी चाहते हैं जहां हम स्क्रॉल गति में वास्तविक संशोधन करेंगे। मैंने अपनी संपत्ति को 1 का डिफॉल्ट भी दिया है, जिस गति का मैं उपयोग करने जा रहा हूं वह है .1x से 3x, हालांकि आप आसानी से 1-10 की तरह कुछ कर सकते हैं।

public static double GetScrollSpeed(DependencyObject obj) 
{ 
    return (double)obj.GetValue(ScrollSpeedProperty); 
} 

public static void SetScrollSpeed(DependencyObject obj, double value) 
{ 
    obj.SetValue(ScrollSpeedProperty, value); 
} 

public static readonly DependencyProperty ScrollSpeedProperty = 
    DependencyProperty.RegisterAttached(
    "ScrollSpeed", 
    typeof(double), 
    typeof(ScrollHelper), 
    new FrameworkPropertyMetadata(
     1.0, 
     FrameworkPropertyMetadataOptions.Inherits & FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, 
     new PropertyChangedCallback(OnScrollSpeedChanged))); 

private static void OnScrollSpeedChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) 
{ 
} 

अब है कि हम अपने संलग्न संपत्ति है हम OnScrollSpeedChanged में हम PreviewMouseWheel घटना संभाल कर सकते हैं स्क्रॉल को संभालने के लिए, यह करने के लिए की जरूरत है,। हम पूर्वावलोकनमोउसहेल में हुक करना चाहते हैं, क्योंकि यह एक सुरंग घटना है जो स्क्रॉलव्यूयर मानक माउसहेल ईवेंट को संभालने से पहले होगी।

वर्तमान में, पूर्वावलोकनमाउसहेल हैंडलर FlowDocumentReader या अन्य चीज़ों को ले रहा है जिसे हमने बाध्य किया है, हालांकि हमें स्क्रॉलव्यूअर की आवश्यकता है। चूंकि यह बहुत सी चीजें हो सकती है: ListBox, FlowDocumentReader, WPF Toolkit ग्रिड, स्क्रॉलव्यूयर, आदि, हम ऐसा करने के लिए VisualTreeHelper का उपयोग करने वाली एक छोटी विधि बना सकते हैं। हम पहले से ही जानते हैं कि आने वाली वस्तु निर्भरता ऑब्जेक्ट का कुछ रूप होगा, इसलिए यदि यह मौजूद है तो स्क्रॉलव्यूअर को खोजने के लिए हम कुछ रिकर्सन का उपयोग कर सकते हैं।

public static DependencyObject GetScrollViewer(DependencyObject o) 
{ 
    // Return the DependencyObject if it is a ScrollViewer 
    if (o is ScrollViewer) 
    { return o; } 

    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(o); i++) 
    { 
     var child = VisualTreeHelper.GetChild(o, i); 

     var result = GetScrollViewer(child); 
     if (result == null) 
     { 
      continue; 
     } 
     else 
     { 
      return result; 
     } 
    } 

    return null; 
} 

private static void OnScrollSpeedChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) 
{ 
    var host = o as UIElement; 
    host.PreviewMouseWheel += new MouseWheelEventHandler(OnPreviewMouseWheelScrolled); 
} 

अब हम स्क्रॉलवियर प्राप्त कर सकते हैं हम अंततः स्क्रॉल गति को संशोधित कर सकते हैं। हमें स्क्रॉलस्पेड संपत्ति को निर्भरता ऑब्जेक्ट से प्राप्त करने की आवश्यकता होगी जिसे भेजा जा रहा है। साथ ही, हम तत्व के भीतर मौजूद स्क्रॉलव्यूयर प्राप्त करने के लिए हमारी सहायक विधि का उपयोग कर सकते हैं। एक बार हमारे पास इन दो चीजें हैं, तो हम स्क्रॉलव्यूअर के वर्टिकल ऑफसेट को प्राप्त और संशोधित कर सकते हैं। मैंने पाया कि MouseWheelEventArgs.Delta को विभाजित करना, जो कि माउस व्हील बदल गया है, 6 तक लगभग डिफ़ॉल्ट स्क्रॉल गति प्राप्त होती है। इसलिए, अगर हम इसे हमारे स्क्रॉलस्पीड संशोधक द्वारा गुणा करते हैं, तो हम नया ऑफसेट मान प्राप्त कर सकते हैं। इसके बाद हम ScrollVoVerticalOffset विधि का उपयोग करके ScrollViewer के वर्टिकलऑफसेट को सेट कर सकते हैं।

private static void OnPreviewMouseWheelScrolled(object sender, MouseWheelEventArgs e) 
{ 
    DependencyObject scrollHost = sender as DependencyObject; 

    double scrollSpeed = (double)(scrollHost).GetValue(Demo.ScrollSpeedProperty); 

    ScrollViewer scrollViewer = GetScrollViewer(scrollHost) as ScrollViewer; 

    if (scrollViewer != null) 
    { 
     double offset = scrollViewer.VerticalOffset - (e.Delta * scrollSpeed/6); 
     if (offset < 0) 
     { 
      scrollViewer.ScrollToVerticalOffset(0); 
     } 
     else if (offset > scrollViewer.ExtentHeight) 
     { 
      scrollViewer.ScrollToVerticalOffset(scrollViewer.ExtentHeight); 
     } 
     else 
     { 
      scrollViewer.ScrollToVerticalOffset(offset); 
     } 

     e.Handled = true; 
    } 
    else 
    { 
     throw new NotSupportedException("ScrollSpeed Attached Property is not attached to an element containing a ScrollViewer."); 
    } 
} 

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

<UniformGrid Columns="2"> 
    <DockPanel> 
     <Slider DockPanel.Dock="Top" 
      Minimum=".1" 
      Maximum="3" 
      SmallChange=".1" 
      Value="{Binding ElementName=uiListBox, Path=(ScrollHelper:Demo.ScrollSpeed)}" /> 
     <ListBox x:Name="uiListBox"> 
      <!-- Items --> 
     </ListBox> 
    </DockPanel> 
    <DockPanel> 
     <Slider DockPanel.Dock="Top" 
      Minimum=".1" 
      Maximum="3" 
      SmallChange=".1" 
      Value="{Binding ElementName=uiListBox, Path=(ScrollHelper:Demo.ScrollSpeed)}" /> 
     <FlowDocumentReader x:Name="uiReader" 
      ViewingMode="Scroll"> 
      <!-- Flow Document Content --> 
     </FlowDocumentReader> 
    </DockPanel> 
</UniformGrid> 

अब, जब चलते हैं, हम स्लाइडर का उपयोग प्रत्येक कॉलम, मजेदार सामान में स्क्रॉलिंग गति को संशोधित करने के लिए कर सकते हैं।

+1

बहुत बढ़िया! मैं एमवीवीएम के समान कुछ उपयोग कर रहा हूं और आपका दृष्टिकोण पूरी तरह से काम करेगा। मैं इसे लागू करने की उम्मीद कर रहा हूं। Thanx! – Christo

+1

यह शानदार ढंग से काम करता है! मुझे इसे संकलित और काम करने के लिए इसे थोड़ा सा ट्विक करना पड़ा। – Christo

0

स्क्रॉल ईवेंट का उपयोग करने के बजाय, माउसहेल ईवेंट को कैप्चर करें।

<FlowDocumentReader MouseWheel="..."> 
+0

मैं इसे आज़माउंगा, शायद मैं काम करने के लिए कुछ प्राप्त कर सकता हूं। मैं इस विचार से काफी इस्तीफा दे रहा हूं कि संभवतः बहुत सारे कोड लिखने के बिना इसे हासिल करना बहुत कठिन होगा। – Christo

संबंधित मुद्दे