2010-02-16 24 views
8

ठीक ज़ूम करने के लिए, मैं समझ गए होंगे कि कैसे LayoutTransform और ScaleTransform का उपयोग करके, ज़ूम करने के लिए UI तत्व की मेरी ग्रिड प्राप्त करने के लिए। जो मुझे समझ में नहीं आता है, यह है कि मैं इसे देखने के लिए CTRL + MouseWheelUp \ Down का जवाब देने के लिए अपना दृश्य कैसे प्राप्त कर सकता हूं, और एमवीवीएम पैटर्न में कोड को कैसे फ़िट कर सकता हूं।माउसव्हील MouseBinding WPF और MVVM

मेरा पहला विचार ZoomFactor एक संपत्ति के रूप में संग्रहीत करते हैं और इसे समायोजित करने के लिए एक आदेश के लिए बाध्य किया गया था।

मैं की तरह कुछ देख रहा था:

<UserControl.InputBindings> 
<MouseBinding Command="{Binding ZoomGrid}" Gesture="Control+WheelClick"/> 
</UserControl.InputBindings> 

लेकिन मैं 2 मुद्दों देखें:

1) मुझे नहीं लगता कि वहाँ एक रास्ता बताने के लिए है कि क्या पहिया ऊपर और नीचे ले जाया गया था या है, न ही मैं देख सकता हूं कि कितना निर्धारित करना है। मैंने MouseWheelEventArgs.Delta देखा है, लेकिन यह नहीं पता कि इसे कैसे प्राप्त किया जाए।

2) viewmodel पर एक आदेश के लिए बाइंडिंग सही नहीं लगता है, यह सख्ती से एक दृश्य की बात है के रूप में।

चूंकि ज़ूम सख्ती से केवल यूआई देखें, मैं सोच रहा हूं कि वास्तविक कोड कोड-पीछे में जाना चाहिए।

आप इसे कैसे लागू करेंगे?

पेज, मैं एमवीवीएम के लिए सिंच का उपयोग कर .net \ wpf 4.0 का उपयोग कर रहा हूं।

+0

इसे वेब पर मिला, यह मदद कर सकता है ... http://social.technet.microsoft.com/wiki/contents/articles/18199.event-handling-in-an-mvvm-wpf-plication .aspx – dunamis

उत्तर

5

मैं सुझाव दूंगा कि आप अपने वीएम में एक सामान्य ज़ूम कमांड लागू करें। आदेश या (शायद और भी आसान) एक नए ज़ूम स्तर के साथ parameterized किया जा सकता है, तो आप को लागू कर सकता है एक IncreaseZoomCommand और DecreaseZoomCommand। फिर माउस व्हील ईवेंट के ईवेंट तर्कों को संसाधित करने के बाद इन आदेशों को कॉल करने के लिए दृश्य के कोड का उपयोग करें। यदि डेल्टा सकारात्मक है, तो ज़ूम इन करें, यदि ऋणात्मक ज़ूम आउट हो।

पीछे कोड की कुछ पंक्तियों का उपयोग करके इस समस्या को हल करने में कोई हानि नहीं है। एमवीवीएम का मुख्य विचार यह है कि, आप उस ऑब्जेक्ट में अपने दृश्य की लगभग पूरी स्थिति को ट्रैक और संशोधित करने में सक्षम हैं जो यूआई पर निर्भर नहीं है (टेस्टेबिलिटी को बढ़ाता है)। नतीजतन, नए व्यूपोर्ट की गणना जो ज़ूम का परिणाम है वीएम में किया जाना चाहिए और कोड के पीछे नहीं होना चाहिए।

पीछे कोड में मौजूद टेस्टेबिलिटी का छोटा अंतर या तो स्वचालित यूआई परीक्षणों से अवहेलना या कवर किया जा सकता है। स्वचालित यूआई परीक्षण, हालांकि, बहुत महंगा हो सकता है।

0

मुझे लगता है कि आप जो करने की कोशिश कर रहे हैं वह दृश्य से बहुत अधिक संबंधित है, इसलिए आपके कोड में कोड को कम करने में कोई हानि नहीं है (कम से कम मेरी राय में), हालांकि मुझे यकीन है कि इसे संभालने के सुरुचिपूर्ण तरीके हैं जैसे कि यह अधिक दृश्यमान आधारित है।

आपको OnPrevewMouseWheel ईवेंट में पंजीकरण करने में सक्षम होना चाहिए, जांचें कि क्या उपयोगकर्ता को नियंत्रण कुंजी मिल गई है और ज़ूमिंग प्रभाव को प्राप्त करने के लिए अपने ज़ूम कारक को तदनुसार बदलना है।

0

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

तथ्य यह है कि MouseEventArgs (और इस प्रकार डेल्टा) को पकड़ने का एकमात्र तरीका कोड के पीछे है, इसलिए आपको वहां की आवश्यकता है (इसके लिए कोई तर्क आवश्यक नहीं है) और इसे अपने दृश्य मॉडल पर पास करें ओली सुझाव दिया।

फ्लिप पक्ष पर आप दृश्य से संबंधित किसी भी सम्मेलन से अनजान रखने के लिए एक अधिक सामान्य डेल्टा (उदाहरण के लिए इसे दृश्य मॉडल के चरण के रूप में पार करने से पहले इसे 120 से विभाजित करना) का उपयोग करना चाह सकते हैं या ओएस। यह दृश्य मॉडल में आपके कोड का अधिकतम पुन: उपयोग करने की अनुमति देगा।

1

तुम्हारे पीछे आप MVVM प्रकाश की EventToCommand कार्यक्षमता का उपयोग कर सकते हैं कोड का उपयोग नहीं करना चाहते हैं:

दृश्य:

<... 
    xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF4" 
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
    ...> 
<i:Interaction.Triggers> 
     <i:EventTrigger EventName="PreviewMouseWheel"> 
      <cmd:EventToCommand Command="{Binding 
    Path=DataContext.ZoomCommand, 
    ElementName=Root, Mode=OneWay}" 
     PassEventArgsToCommand="True" /> 
     </i:EventTrigger> </i:Interaction.Triggers> 

ViewModel:

ZoomCommand = new RelayCommand<RoutedEventArgs>(Zoom); 
... 
public void Zoom(RoutedEventArgs e) 
{ 
    var originalEventArgs = e as MouseWheelEventArgs; 
    // originalEventArgs.Delta contains the relevant value 
} 

मुझे आशा है कि इस मदद करता है कोई व्यक्ति। मुझे पता है कि सवाल पुराना है ...

+0

मुझे यह अजीब लगता है कि आपका वीएम एक रूटेड घटना होगी – Alan

8

असली anwser अपना माउसजेशर लिखना है, जो आसान है।

<MouseBinding Gesture="{x:Static me:MouseWheelGesture.CtrlDown}" 
       Command="me:MainVM.SendBackwardCommand" /> 






public class MouseWheelGesture : MouseGesture 
    { 
    public WheelDirection Direction { get; set; } 


    public static MouseWheelGesture CtrlDown 
    { 
     get 
     { 
     return new MouseWheelGesture(ModifierKeys.Control) { Direction = WheelDirection.Down }; 
     } 
    } 


    public MouseWheelGesture(): base(MouseAction.WheelClick) 
    { 
    } 

    public MouseWheelGesture(ModifierKeys modifiers) : base(MouseAction.WheelClick, modifiers) 
    { 
    } 



    public override bool Matches(object targetElement, InputEventArgs inputEventArgs) 
    { 
     if (!base.Matches(targetElement, inputEventArgs)) return false; 
     if (!(inputEventArgs is MouseWheelEventArgs)) return false; 
     var args = (MouseWheelEventArgs)inputEventArgs; 
     switch (Direction) 
     { 
     case WheelDirection.None: 
      return args.Delta == 0; 
     case WheelDirection.Up: 
      return args.Delta > 0; 
     case WheelDirection.Down: 
      return args.Delta < 0; 
     default: 
      return false; 
     } 
    } 



    public enum WheelDirection 
    { 
     None, 
     Up, 
     Down, 
    } 

    } 
0

पूरी समस्या से बचने के लिए, वहाँ एक और विकल्प है: XAML में एक ContentPresenter प्रयोग और यह सामग्री एक viewmodel वस्तु के लिए बाध्य किया जा रहा है करते हैं। - व्यूमोडेल के भीतर mousewheel घटनाओं को संभालें।

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