2011-12-23 12 views
5

सभी मेनू/contextmenus/टूलबार WPF में मैं का उपयोग इस तरह काफी ViewModel कोड घोषित किये गए हैं:'शुद्ध' एमवीवीएम में मेनूइटम कीबोर्ड शॉर्टकट्स?

MenuService.Add(new MenuItem() 
    { 
    Header = "DoStuff", 
    Command = new relayCommand(DoStuff,() => CanDoStuffExecute()) 
    // some more properties like parent item/image/... 
    }); 

MenuService एक भी बाध्यकारी बिंदु जो MenuItem की एक पदानुक्रमित सूची है और वास्तविक मेनू के लिए बाध्य हो जाता है प्रदान करता है Xaml में आइटम स्रोत।

यह बहुत अच्छा काम करता है और अब मैं एक ही सुविधाजनक तरीके से कीबोर्ड शॉर्टकट जोड़ना चाहता हूं। आदर्श रूप में MenuItem प्रकार System.Windows.Input.KeyGesture की संपत्ति मिलेगा तो मैं बस लिख सकते हैं

Shortcut = new KeyGesture(Key.D, ModifierKeys.Control) 

जो आइटम की कमान में परिणाम होगा विंडो मेनू का मालिक में Ctrl + D मार का आह्वान किया जा रहा है, और जो भी होगा मेनू में स्वचालित रूप से "Ctrl + D" प्रदर्शित करने के लिए नेतृत्व करें।

हालांकि मैं यहां खो गया हूं: मैं डेटाबेसइंड के माध्यम से MenuItem.InputBindings संग्रह सेट करना चाहता था लेकिन यह केवल-प्राप्त है। वैसे भी मैं इसमें सामान कैसे प्राप्त कर सकता हूं? या क्या कोई एमवीवीएम फ्रेमवर्क है जो पहले से ही इस तरह का समर्थन करता है? अधिकांश q & मुझे कीबोर्ड शॉर्टकट पर एक एक्सएमएल के माध्यम से शॉर्टकट सेट करने के बारे में है, जो कि कोई मदद नहीं है।

अद्यतन

'relaycommand routeduicommand और बनाम' relaycommand keygesture 'आदि के लिए खोज करने के लिए पर्याप्त जानकारी प्रकट हालांकि hacky समाधान एक काम कर साथ आने के लिए किया था। वहां निश्चित रूप से अन्य और बेहतर तरीके हैं, लेकिन फिलहाल यह मेरे लिए अति प्राथमिकता है और यह काम पूरी तरह से करता है। मैं इस तरह MenuItem वर्ग के लिए दो गुण कहा:

//Upon setting a Gesture, the original command is replaced with a RoutedCommand 
//since that automatically gives us proper display of the keyboard shortcut. 
//The RoutedCommand simply calls back into the original Command. 
//It also sets the CommandBinding property, which still has to be added to the 
//CommandBindingCollection of either the bound control or one of it ancestors 
public InputGesture Gesture 
{ 
    set 
    { 
    var origCmd = Command; 
    if(origCmd == null) 
     return; 
    var routedCmd = new RoutedCommand(Header, 
     typeof(System.Windows.Controls.MenuItem), 
     new InputGestureCollection { value }); 
    CommandBinding = new CommandBinding(routedCmd, 
     (sender, args) => origCmd.Execute(args.Parameter), 
     (sender, args) => { args.CanExecute = origCmd.CanExecute(args.Parameter); }); 
    Command = routedCmd; 
    } 
} 

//CommandBinding created when setting Gesture 
public CommandBinding CommandBinding { get; private set; } 

तो यह (यानी कोड में कीबोर्ड शॉर्टकट जहां वे आसानी से विन्यास आदि जोड़ने) कार्यक्षमता मैं मूल रूप से करने के लिए कहा देता है। बाकी सब कुछ कमांडबिंडिंग पंजीकृत है। फिलहाल यह उन सभी को एप्लिकेशन में जोड़कर किया जाता है। वर्तमान। मेन विन्डो.कॉमंड बाइंडिंग्स।

उत्तर

3

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

संपत्ति मूल्य, और कमांड आपके दृश्य-मॉडल के लिए हैं, ताकि आप अन्य दृश्यों के लिए इस व्यू-मॉडल का पुन: उपयोग कर सकें और इसके लिए आसानी से इकाई-परीक्षण भी बना सकें। दृश्य-मॉडल में आपके कीबोर्ड शॉर्टकट को कार्यान्वित करने से टेस्टेबिलिटी में मदद मिलेगी? और अन्य विचारों में उपयोग के लिए, कोई तर्क दे सकता है कि वास्तविक शॉर्टकट नए दृश्य पर लागू नहीं हो सकते हैं, इसलिए वह नहीं है। आपके पास पाठ्यक्रम के अन्य कारण हो सकते हैं - लेकिन मेरा सुझाव है कि आप इन्हें एक्सएएमएल में परिभाषित करने पर विचार कर सकते हैं।

जोड़ा, के जवाब में अपने comment-

आप बहुत सही कर रहे हैं - और मैं कुछ नहीं बल्कि बड़े WPF UX परियोजनाओं है कि किसी भी से बचने के लिए बहुत कोशिश की कोड और अनावश्यक रूप से कुंठित को बंद कर देखा है। मैं जो भी दृष्टिकोण एक कार्य परिणाम उत्पन्न करता हूं, उसका उपयोग करने की कोशिश करता हूं, और जितना आसान हो उतना आसान है।

यहां एक नमूना स्निपेट है जो बस मेनूइटम बनाता है ..

<Menu x:Name="miMain" DockPanel.Dock="Top"> 
    <MenuItem Command="{Binding Path=MyGreatCommand}" Header="DoSomething"/> 

यह मेनू बनाता है। यहां, MyGreatCommand एक ICommand है, और यह केवल दृश्य-मॉडल पर एक संपत्ति है। मैं आम तौर पर जगह है कि एक DockPanel भीतर, StatusBar, संभाल करने आदि

कुंजी इशारा असाइन करने के लिए ..

<Window.InputBindings> 
    <KeyBinding Key="X" Modifiers="ALT" Command="{Binding Path=MyGreatCommand}"/> 

हालांकि, चूंकि आपने उल्लेख किया है कि आप पहले से ही जवाब के लिए खोज की है और केवल XAML पाया - मुझे लगता है कि आप पहले से ही इस दृष्टिकोण की कोशिश कर चुके हैं। मैंने हेडर टेक्स्ट में उस अच्छे दाएं-संरेखित कुंजी-इशारे को प्राप्त करने के लिए उपयोगकर्ता परिभाषित ICommand एस के बजाय RoutedUICommand एस का उपयोग किया है, लेकिन मुझे नहीं पता कि दोनों को कैसे करना है। यदि आप कोड में सभी आदेश और कुंजी-जेस्चर बनाने पर जोर देते हैं, तो आपको RoutedUICommand एस बनाना होगा।

क्यों आप अपने XAML के अलावा अन्य में महत्वपूर्ण-इशारों सेट के लिए इच्छुक रहे हैं?

आप कुछ मेनू आइटम केवल प्रकट करने के लिए जब कुछ राज्यों अपनी व्यू-मॉडल के भीतर बोलबाला पकड़ चाहते हैं, तो आप एक मेनू आइटम के Visibility संपत्ति (जो अन्य मेनू आइटम शामिल कर सकते हैं) Collapsed या Visible करने के लिए बाध्य कर सकते हैं ।

+0

क्या आप कुछ कोड नमूना प्रदान कर सकते हैं? क्या आपका मतलब है कि मुझे xaml में पूरा मेनू परिभाषित करना चाहिए? या सिर्फ शॉर्टकट? मैं देखना चाहता हूं कि .. मुझे वैश्विक 'टूल्स' मेनू जैसी चीज़ों की ज़रूरत है जिसमें प्लगइन्स सबमेनस को इच्छानुसार जोड़ सकते हैं - क्या यह xaml में भी किया जा सकता है? यह भी मान सकते हैं कि यह कर सकता है, यह xaml के साथ कोड कूड़ा होगा, नहीं? अब मुझे एक मेनू कमांड जोड़ने की जरूरत है जैसा कोड दिखाया गया है। यह उतना छोटा और आसान है जितना इसे प्राप्त हो सकता है और यह बेहद काम करता है। बीटीडब्ल्यू आपकी ईंट की दीवार 2 दिशाओं में काम करती है: मुझे अभी भी एक बड़े पैमाने पर ऐप देखना है जहां कोड में कोई एकल यूएक्स टुकड़ा परिभाषित नहीं किया गया है .. यह एक मिथक है। – stijn

+0

आप बिल्कुल सही हैं - और मैंने कुछ बड़ी डब्लूपीएफ यूएक्स परियोजनाओं को देखा है जिन्होंने किसी भी कोड से बचने के लिए वास्तव में कड़ी मेहनत की है - और अनावश्यक रूप से घुसपैठ कर घायल हो गए हैं। मैं जो भी दृष्टिकोण काम करता हूं उसका उपयोग करने की कोशिश करता हूं और सबसे सरल है। यहां एक नमूना स्निपेट है (क्षमा करें, इस वेबसाइट पर इसे प्रारूपित करने के लिए क्षमा करें) .. '<मेनू x: नाम = "miMain" DockPanel.Dock = "Top"> – JamesWHurst

+1

संपादित करें आपका उत्तर, कोड पेस्ट करें, इसे चुनें और * कोड नमूना * बटन पर क्लिक करें .. – stijn

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