2010-06-29 14 views
30

समस्या का वर्णनWPF अनुप्रयोग पूरी तरह से खिड़की पर ध्यान केंद्रित खो देता करीब

अगर मैं एक माता पिता के खिड़की के लिए विंडो के मालिक की स्थापना के माध्यम से एक बच्चे को विंडो के रूप में एक गैर-मोडल विंडो करें, और उसके भीतर से एक संदेशबॉक्स दिखाने अगर मैं बाल खिड़की बंद करता हूं तो यह बच्चा खिड़की, पैरेंट विंडो फोकस खो जाएगी। यदि विंडोज एक्सप्लोरर या कोई अन्य ऐप खुला है, तो इस ऐप को फोकस मिलेगा और मेरी मुख्य विंडो छिपी जाएगी।

यह एक ज्ञात समस्या प्रतीत होता है क्योंकि मैंने इसे newsgroups में देखा, लेकिन मैंने एक अच्छा समाधान नहीं देखा है। ऑनडिक्टिवेट में मालिक को शून्य पर सेट करना एक विकल्प नहीं है। संदेश बॉक्स को शून्य और रीसेट करने से पहले मालिक को सेट करने से पहले मदद नहीं मिलती है। ऑनक्लोज्ड इवेंट में मालिक को शून्य पर सेट करने से भी मदद नहीं मिलती है।

सरल समाधान

पाया आप एक ही समस्या का अनुभव के रूप में मैं का वर्णन किया है, तो सभी बच्चे खिड़कियों के OnClosing में निम्न कोड डालें।

void OnClosing(System.ComponentModel.CancelEventArgs e) 
    base.OnClosing(e); 
    if (null != Owner) { 
     Owner.Activate(); 
    } 
    // .... 

इसके बाद किसी और प्रसंस्करण तर्क के बाद, संदेशबॉक्स खोलने को भी सहन किया जा सकता है।

उदाहरण-संहिता

मुद्दा बहुत बड़ा के रूप में मैंने सोचा था कि हो रहा है। यदि संदेश बॉक्स खोला जाएगा और बच्चे की विंडो बंद हो जाएगी (कोड को एक लोड किए गए ईवेंट-विंडो के हैंडलर में कॉपी करें) तो निम्न उदाहरण पैरेंट विंडो का फोकस हटा देगा।

Window firstChildWindow = new Window() { 
    Title = "Floating Window", Width = 100, Height = 70 
}; 
firstChildWindow.Owner = Window.GetWindow(this); 

Button button = new Button() { Content="MessageBox"}; 
button.Click += delegate { 
    MessageBox.Show("Klicking her breaks the focus-chain."); }; 
firstChildWindow.Content = button; 
firstChildWindow.Show(); 

इसके अलावा इस उदाहरण टूट जाता है ध्यान केंद्रित श्रृंखला:

Window firstChildWindow = new Window() { 
    Title = "Floating Window", Width = 100, Height = 70 
}; 
firstChildWindow.Owner = Window.GetWindow(this); 
firstChildWindow.Show(); 

Window secondChildWindow = new Window() { 
    Title="Second Window",Width=100,Height=70}; 
secondChildWindow.Content = new TextBlock() { 
    Text="SecondWindow"}; 
secondChildWindow.Owner = firstChildWindow; 
secondChildWindow.Show(); 

कोई इस समस्या के लिए एक प्रस्ताव है। मैं डिस्पैचर या डिस्पैटर टाइमर के साथ बंद होने के बाद माता-पिता को ध्यान देने के लिए एक हैक के बारे में सोचता हूं या शायद यह बंद करने पर माता-पिता को मैन्युअल बल फोकस करने के लिए काम करेगा लेकिन यह सब मुझे बहुत अशुद्ध लगता है (और यह भी थोड़ा जटिल है मेरे माता-पिता की अधिक सक्रिय स्वामित्व वाली खिड़कियां हैं, जैसा कि मेरे वर्तमान ऐप में है)।

कोई भी इस के लिए एक साफ समाधान जानता है?

संसाधन

MSDN Description (बुला खोला गैर मोडल खिड़कियों के लिए टिप्पणी के नीचे देख दिखाएँ())

Same problem on msdn forums without appropriate solution

कृपया यह भी देखें: Instable focus of WPF apps

+0

मैंने आपके प्रश्न को पूरी तरह गलत समझा, क्षमा करें, मैंने अपना जवाब हटा दिया है। – Nir

+0

कोई समस्या नहीं, वैसे भी उत्तर के लिए धन्यवाद - मैंने अपनी समस्या को थोड़ा और स्पष्ट करने के लिए विवरण बदल दिया :) – HCL

उत्तर

22

यहां सबसे अधिक संभावना है कि आपके पास दो स्वतंत्र शीर्ष स्तर की खिड़कियां हैं और उनमें से एक बंद है। यह कभी-कभी किसी अन्य एप्लिकेशन पर जाने के लिए फोकस का कारण बनता है।

यह तब भी होता है जब एक खिड़कियां एक दूसरे के मालिक हों, जो बदले में एक तिहाई हो। Win32 एपीआई में संभावित BUG लेकिन यह हमारे साथ हमेशा के लिए बहुत अच्छा भाग्य तय कर रहा है।

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

+0

दूसरा पैराग्राफ बिल्कुल मेरी समस्या का वर्णन करता है। क्या आपके पास इस पर अधिक जानकारी है? – HCL

+0

दुर्भाग्य से मैं नहीं करता हूं। मुझे बहुत समय पहले Win32 कोड लिखने में बग का सामना करना पड़ा। एकमात्र समाधान WM_CLOSE को संसाधित करना था और सेटफोकस() को विंडो के स्वामी पर वापस कॉल करना था। WinForms में, WM_CLOSE ϞFormClosing में अनुवाद करता है, और फॉर्म क्लास पर फ़ोकस() विधि है। WPF के लिए समान सामान होना चाहिए। – Joshua

+2

वह वहां कैसे पहुंचा? :) http://en.wiktionary.org/wiki/%CF%9E – porges

0

यह संभव है लिखने के लिए अपने अपना संदेशबॉक्स, जब आप दिखाए जाते हैं तो आप फ्लोटर को पूरी स्क्रीन अक्षम कर सकते हैं।

आप कैलिब्रर्न एमवीवीएम फ्रेमवर्क नमूना की जांच करते हैं, तो सेवा के रूप में संदेशबॉक्स का एक अच्छा कार्यान्वयन है।

0

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

19

यह एक बहुत ही कष्टप्रद बग है, सबसे आम प्रदान की समाधान है:

Window_Unloaded या Window_Closing स्थिति में कॉल Me.Owner.Focus

लेकिन यह अभी भी 100% काम नहीं करता है, फिर भी आप फोकस को सही ढंग से बहाल करने से पहले, फ़ोरग्राउंड (बहुत संक्षेप में) चमकते पृष्ठभूमि-विंडो को देखते हैं।

कॉल Me.Owner.ActivateMe.Close से पहले (या _Closing घटना में):

मैं एक तरीका है जिसके बेहतर काम करता है पाया।

+0

ऐसा लगता है कि मुझे यह करना होगा। मैं इसे एक पुन: प्रयोज्य व्यवहार में डाल रहा हूं, हालांकि मेरे सभी विचार अच्छे उपाय के लिए इसका उपयोग कर सकते हैं। एक साइड नोट के रूप में, ऐसा लगता है कि मुझे इस मुद्दे को ओपी के दो अलग-अलग परिदृश्यों के साथ अलग-अलग परिदृश्य के साथ मिलता है। – Andy

+0

मैंने मालिक के अलावा मालिक.फोकस() का भी उपयोग किया। सक्रिय(); अन्यथा, मेरे कीबोर्ड शॉर्टकट तुरंत काम नहीं कर रहे थे। – scottheckel

2

शायद मैं इस मामले पर काफी देर हो चुकी हूं।
@HCL इस समस्या()MessageBoxOptions.None को MessageBox.show की विकल्पों पैरामीटर की स्थापना करके और अधिक आसानी से हल किया जा सकता है।

चीयर्स ...

0

Johsua के .Activate (ऊपर देखें) समाधान खिड़की प्रकार के सभी प्रकार के साथ काफी अच्छी तरह से काम करता है। कम से कम यह मेरे लिए चाल है।

0

मुझे एक ही समस्या थी। मेरे पास एक मुख्य खिड़की थी, जहां मालिक की संपत्ति के माध्यम से उस खिड़की को बाकी बाल खिड़कियां असाइन की गई थीं। यदि मुख्य खिड़की में दो या दो से अधिक बच्चे थे, तो दूसरे दूसरे बच्चे के बाद, ऐप फोकस खो देता है। मैंने बच्चे के साथ चाल का इस्तेमाल किया .ऑनर = करीब से पहले शून्य, लेकिन फिर मेरी अगली बच्ची खिड़की फोकस खो देती है। मैंने इसे सभी बच्चों को प्राप्त करके संभाला और बच्चे को बंद करने से पहले अंतिम पर ध्यान केंद्रित किया। यहां कोड उदाहरण है:

private void OnClosing(object sender, CancelEventArgs cancelEventArgs) 
     { 
      var childWindows = (sender as Window).Owner.OwnedWindows; 
      if (childWindows.Count - 2 >= 0) 
       childWindows[childWindows.Count - 2].Focus(); 
      else 
      { 
       (sender as Window).Owner.Focus(); 
      } 
      (sender as Window).Owner = null; 
     } 
संबंधित मुद्दे