2010-10-08 13 views
19
संभाल

क्या मैं वास्तव में चाहते हैं कि माउस क्लिक घटनाओं पर ध्यान नहीं देता, लेकिन अभी भी माउस दर्ज करें और घटनाओं छोड़ फंसा लेती है IsHitTestVisible का एक संस्करण है।WPF: ओवरले/adorner पर माउस क्लिक पर ध्यान न दें, लेकिन mouseenter घटना

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

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

समस्या: अगर मैं सही पर IsHitTestVisible सेट माउस के माध्यम से पारित करने के लिए क्लिक करता है अनुमति देने के लिए, मैं mouseenter घटनाओं नहीं मिलता है।

क्या IsHitTestVisible True को छोड़ने का कोई आसान तरीका है, और उसके बाद 2-3 घटनाओं को सजाने के नीचे सही नियंत्रण में पास करें? मैं ऐसे समाधान की तलाश में हूं जिसमें कर्सर के नीचे नियंत्रण क्या है, इसकी गणना शामिल नहीं है, क्योंकि डब्ल्यूपीएफ मेरे लिए यह करने में स्पष्ट रूप से सक्षम है।

वैकल्पिक रूप से, क्या मैं IsHitTestVisible को गलत पर सेट कर सकता हूं लेकिन फिर यह निर्धारित करने के लिए एक और सरल विधि का उपयोग करें कि माउस कब सजाए जाने पर है?

अद्यतन: मैं अभी भी एक जवाब के लिए उम्मीद कर रहा हूँ, लेकिन अब के रूप में सबसे होनहार समाधान IsHitTestVisible सच छोड़ने जा रहा है, और WPF का उपयोग कर एपीआई परीक्षण हिट यह पता लगाने की नियंत्रण किस प्रकार माउस के नीचे था कर्सर; अगर यह एक था, तो मुझे पता था, मैं इसे एक क्लिक कमांड भेजूंगा। सुनिश्चित नहीं है कि यह करने योग्य है, हालांकि; अब के रूप में मेरे ओवरले को खारिज कर दिया गया है ताकि उपयोगकर्ता को दो बार क्लिक करना होगा।

धन्यवाद!

+0

क्या आपने कभी इसे हल किया है? मेरे पास बिल्कुल वही आवश्यकता है। – Grokys

उत्तर

7

चूंकि IsHitTestVisible = "गलत" सभी माउस इंटरैक्शन को अक्षम करता है, यह ऐसा करने का कोई साफ तरीका प्रतीत नहीं होता है। मैंने कोशिश की

  • स्थापना IsHitTestVisible = "false" OnPreviewMouseDown में और उसके बाद फिर से क्लिक करने UIAutomation का उपयोग कर adorner लेकिन कोई पासा
  • adorner के तहत एक "अदृश्य" तत्व के लिए अपारदर्शिता बाइंडिंग ताकि क्लिक के माध्यम से पारित होगा । यह ठीक से पारित हो गया, लेकिन निश्चित रूप से समस्या अगले स्तर पर समान थी इसलिए कोई पासा नहीं था।

वास्तव में काम करने के लिए यह एकमात्र तरीका लगता है कि ऑनहाउसटाउन में "हैशटस्टेस्टिव =" गलत "सेट करें और फिर SendInput का उपयोग करके एक नया माउसक्लिक अनुकरण करें। बहुत सुंदर नहीं है लेकिन यह काम पूरा हो जाता है।

protected override void OnMouseDown(MouseButtonEventArgs e) 
{ 
    IsHitTestVisible = false; 

    Action action =() => 
    { 
     MouseSimulator.ClickLeftMouseButton(); 
     IsHitTestVisible = true; 
    }; 
    this.Dispatcher.BeginInvoke(action, DispatcherPriority.ContextIdle); 
} 

public class MouseSimulator 
{ 
    [DllImport("user32.dll", SetLastError = true)] 
    static extern uint SendInput(uint nInputs, ref INPUT pInputs, int cbSize); 

    [StructLayout(LayoutKind.Sequential)] 
    struct INPUT 
    { 
     public SendInputEventType type; 
     public MouseKeybdhardwareInputUnion mkhi; 
    } 
    [StructLayout(LayoutKind.Explicit)] 
    struct MouseKeybdhardwareInputUnion 
    { 
     [FieldOffset(0)] 
     public MouseInputData mi; 

     [FieldOffset(0)] 
     public KEYBDINPUT ki; 

     [FieldOffset(0)] 
     public HARDWAREINPUT hi; 
    } 
    [StructLayout(LayoutKind.Sequential)] 
    struct KEYBDINPUT 
    { 
     public ushort wVk; 
     public ushort wScan; 
     public uint dwFlags; 
     public uint time; 
     public IntPtr dwExtraInfo; 
    } 
    [StructLayout(LayoutKind.Sequential)] 
    struct HARDWAREINPUT 
    { 
     public int uMsg; 
     public short wParamL; 
     public short wParamH; 
    } 
    struct MouseInputData 
    { 
     public int dx; 
     public int dy; 
     public uint mouseData; 
     public MouseEventFlags dwFlags; 
     public uint time; 
     public IntPtr dwExtraInfo; 
    } 
    [Flags] 
    enum MouseEventFlags : uint 
    { 
     MOUSEEVENTF_MOVE = 0x0001, 
     MOUSEEVENTF_LEFTDOWN = 0x0002, 
     MOUSEEVENTF_LEFTUP = 0x0004, 
     MOUSEEVENTF_RIGHTDOWN = 0x0008, 
     MOUSEEVENTF_RIGHTUP = 0x0010, 
     MOUSEEVENTF_MIDDLEDOWN = 0x0020, 
     MOUSEEVENTF_MIDDLEUP = 0x0040, 
     MOUSEEVENTF_XDOWN = 0x0080, 
     MOUSEEVENTF_XUP = 0x0100, 
     MOUSEEVENTF_WHEEL = 0x0800, 
     MOUSEEVENTF_VIRTUALDESK = 0x4000, 
     MOUSEEVENTF_ABSOLUTE = 0x8000 
    } 
    enum SendInputEventType : int 
    { 
     InputMouse, 
     InputKeyboard, 
     InputHardware 
    } 

    public static void ClickLeftMouseButton() 
    { 
     INPUT mouseDownInput = new INPUT(); 
     mouseDownInput.type = SendInputEventType.InputMouse; 
     mouseDownInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_LEFTDOWN; 
     SendInput(1, ref mouseDownInput, Marshal.SizeOf(new INPUT())); 

     INPUT mouseUpInput = new INPUT(); 
     mouseUpInput.type = SendInputEventType.InputMouse; 
     mouseUpInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_LEFTUP; 
     SendInput(1, ref mouseUpInput, Marshal.SizeOf(new INPUT())); 
    } 
} 
+0

हम इस परियोजना में सख्ती से WPF जा रहे हैं, कोई विरासत सामग्री की अनुमति नहीं है। लेकिन सुझाव के लिए धन्यवाद। – stone

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