2009-12-14 8 views
14

मेरे डब्ल्यूपीएफ एप्लिकेशन में मैं एक कमांड में एक इनपुट इशारा संलग्न करना चाहता हूं ताकि इनपुट इशारा मुख्य विंडो में विश्व स्तर पर उपलब्ध हो, चाहे कोई नियंत्रण किस पर केंद्रित हो।डब्ल्यूपीएफ: एक कुंजी इशारा चोरी करने से नियंत्रण को कैसे रोकें?

मेरे मामले में मैं Key.PageDown को एक कमांड में बांधना चाहता हूं, हालांकि, जैसे ही कुछ नियंत्रण फोकस प्राप्त करते हैं (जैसे टेक्स्टबॉक्स या ट्री व्यू कंट्रोल), इन नियंत्रणों को मुख्य ईवेंट प्राप्त होते हैं और कमांड अब ट्रिगर नहीं होता है। इन नियंत्रणों में कोई विशिष्ट CommandBindings या InputBindings परिभाषित नहीं है।

यह मैं अपने इनपुट इशारा कैसे परिभाषित है:

XAML:

<Window x:Class="Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Window1" Height="300" Width="300" > 
    <StackPanel> 
     <TreeView> 
      <TreeViewItem Header="1"> 
       <TreeViewItem Header="1.1"></TreeViewItem> 
       <TreeViewItem Header="1.2"></TreeViewItem> 
      </TreeViewItem> 
      <TreeViewItem Header="2" ></TreeViewItem> 
     </TreeView> 
     <TextBox /> 
     <Label Name="label1" /> 
    </StackPanel> 
</Window> 

कोड:

using System; 
using System.Windows; 
using System.Windows.Input; 

public static class Commands 
{ 
    private static RoutedUICommand _myCommand; 

    static Commands() 
    { 
     _myCommand = new RoutedUICommand("My Command", 
      "My Command", 
      typeof(Commands), 
      new InputGestureCollection() 
       { 
        new KeyGesture(Key.PageDown, ModifierKeys.None) 
       }); 
    } 

    public static ICommand MyCommand 
    { 
     get { return _myCommand; } 
    } 
} 

public partial class Window1 : Window 
{ 
    public Window1() 
    { 
     InitializeComponent(); 

     CommandBinding cb = new CommandBinding(); 
     cb.Command = Commands.MyCommand; 
     cb.Executed += new ExecutedRoutedEventHandler(cb_Executed); 
     cb.CanExecute += new CanExecuteRoutedEventHandler(cb_CanExecute); 
     this.CommandBindings.Add(cb); 
    } 

    void cb_CanExecute(object sender, CanExecuteRoutedEventArgs e) 
    { 
     e.CanExecute = true; 
    } 

    void cb_Executed(object sender, ExecutedRoutedEventArgs e) 
    { 
     this.label1.Content = string.Format("My Command was executed {0}", DateTime.Now); 
    } 
} 

मैं पहले से ही के रूप में व्यवहार यह था खिड़की के PreviewKeyDown घटना को पकड़ने और यह अंकन की कोशिश की वांछित प्रभाव नहीं। मैंने Focusable संपत्ति को false पर भी सेट किया है। इससे टेक्स्टबॉक्स नियंत्रणों में मदद मिली, लेकिन TreeView के लिए नहीं (और अवांछित प्रभाव है, कि टेक्स्टबॉक्स अब संपादित नहीं किया जा सकता है, इसलिए यह मेरे लिए समाधान नहीं है)।

तो मेरा सवाल यह है कि मैं एक कुंजीपटल शॉर्टकट कैसे परिभाषित कर सकता हूं जो मुख्य विंडो में हर जगह काम करता है?

उत्तर

10

निम्नलिखित कार्यवाही में विंडो को वैश्विक स्तर पर रखने का वांछित प्रभाव प्रतीत होता है; हालांकि, मैं अभी भी आश्चर्य है WPF में यह करने के लिए कोई आसान तरीका है कि क्या वहाँ:

private void Window_PreviewKeyDown(object sender, KeyEventArgs e) 
{ 
    foreach (InputBinding inputBinding in this.InputBindings) 
    { 
     KeyGesture keyGesture = inputBinding.Gesture as KeyGesture; 
     if (keyGesture != null && keyGesture.Key == e.Key && keyGesture.Modifiers == Keyboard.Modifiers) 
     { 
      if (inputBinding.Command != null) 
      { 
       inputBinding.Command.Execute(0); 
       e.Handled = true; 
      } 
     } 
    } 

    foreach (CommandBinding cb in this.CommandBindings) 
    { 
     RoutedCommand command = cb.Command as RoutedCommand; 
     if (command != null) 
     { 
      foreach (InputGesture inputGesture in command.InputGestures) 
      { 
       KeyGesture keyGesture = inputGesture as KeyGesture; 
       if (keyGesture != null && keyGesture.Key == e.Key && keyGesture.Modifiers == Keyboard.Modifiers) 
       { 
        command.Execute(0, this); 
        e.Handled = true; 
       } 
      } 
     } 
    } 
} 

}

+0

आप कमांडबिंडिंग के बजाय इनपुटबिंडिंग संग्रह भी देखना चाहेंगे। कभी-कभी आपके पास कमांडबिंडिंग्स में रूटेड कमांड नहीं होगा ... – Anvaka

+0

हां, मैं इसके बारे में भूल गया, टिप के लिए धन्यवाद :-) –

+0

यह एक लाइफसेवर है। धन्यवाद! – tltjr

4

PreviewKeyDown का उपयोग करना ठीक है क्या आप है ... "PreviewXYZ" घटनाओं नीचे से ऊपर (ताकि खिड़की यह पहली बार हो जाता है, तो नियंत्रण) ... जो आप कर देता है से निकाल दिया जाता है चाहिए जो कुछ भी आप "विंडो" स्तर पर ग्लोबली करना चाहते थे।

फिर, आप "IsHandled = true" कहने का विकल्प चुन सकते हैं जो इसे अगले नियंत्रण में जाने से रोक देगा (जहां तक ​​आप चिंतित हैं), लेकिन आपको ऐसा करने की ज़रूरत नहीं है। यदि आप ईवेंट को बबल करना चाहते हैं, तो बस अपना कोड जोड़ें और "IsHandled" को झूठी छोड़ दें।

+0

यही मैंने कोशिश की। लेकिन फिर मुख्य इशारा भी फ़िल्टर किया जाता है और खिड़की को पारित नहीं किया जाता है। –

+0

पीएस .: क्या इसका मतलब यह है कि मैं अपने आदेशों पर 'इनपुटफेस्टर्स' का उपयोग नहीं कर सकता, बल्कि मैन्युअल रूप से 'पूर्वावलोकनकेडडाउन' में महत्वपूर्ण घटनाओं पर स्विच/केस करना है? मैं उम्मीद कर रहा था कि डब्लूपीएफ में इससे बचना संभव है ... –

+0

ईमानदार होने के लिए, मैं इनपुट इंजेस्टर्स के साथ बहुत अच्छा नहीं हूं (उन्हें शायद एक बार इस्तेमाल किया गया और मैं वह मजबूत नहीं हूं)। मेरा मुद्दा यह था कि आप इसे पूर्वावलोकनकेडाउन के साथ कर सकते हैं।मुझे पता है कि आप पूरी तरह से अपने आदेशों के साथ आ सकते हैं और इशारे का उपयोग कर सकते हैं ... मैंने इसे किया है, लेकिन केवल एक डेमो में और बहुत समय पहले। - शायद मेरे से कोई भी स्मार्ट जल्द ही टिप्पणी करेगा :) –

2

दुर्भाग्य से WPF में कुछ नियंत्रण कुछ कुंजीपटल प्रसंस्करण आंतरिक hardcoded है। मुख्य विंडो में PreviewKeyDown हैंडलर

का जवाब मैं एक कुंजीपटल शॉर्टकट है कि मुख्य विंडो

प्रश्न में हर जगह काम करता है कैसे परिभाषित कर सकते हैं। और हां, इसका मतलब यह है कि आप पूर्वावलोकनकेडडाउन में मुख्य घटनाओं पर स्विच/केस चुनना चाहते हैं ...

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