2008-12-19 16 views
44

मैं ऐसे एप्लिकेशन पर काम कर रहा हूं जो कुछ बच्चे विंडो प्रदर्शित करता है जिसे या तो उपयोगकर्ता द्वारा बंद किया जा सकता है या स्वचालित रूप से बंद हो जाता है। कुछ अपवादों को डिबग करने के दौरान, मुझे पता चला कि मैं Hide() जैसी विधियों को कॉल करने की कोशिश कर रहा था जो पहले ही बंद हो चुके थे; कोड की यह विशेष शाखा दोनों मामलों के लिए आम थी और मैंने यह ध्यान नहीं दिया था।आप कैसे बताते हैं कि एक WPF विंडो बंद है या नहीं?

मेरे पहले विचारों में से एक Window पर एक संपत्ति की तलाश करना था जो इंगित करेगा कि खिड़की बंद कर दी गई थी। मुझे एक नहीं लगता है। WinForms में, मैं IsDisposed संपत्ति को कुछ हद तक विश्वसनीय संकेतक के लिए देखता हूं कि फॉर्म बंद कर दिया गया था (यह विश्वसनीय रूप से एक संवाद के लिए काम नहीं करेगा लेकिन मैं संवाद के साथ काम नहीं कर रहा हूं।) मुझे कुछ भी दिखाई नहीं दे रहा है Window पर समतुल्य। Window.Close() के लिए प्रलेखन विधि द्वारा बदला गया कोई भी गुण इंगित नहीं करता है। क्या मुझे कुछ स्पष्ट याद आ रहा है, या यह जानने का एकमात्र तरीका है कि Closed ईवेंट को संभालने के लिए विंडो बंद कर दी गई है या नहीं? ऐसा लगता है कि एक साधारण कार्य के लिए एक कठोर आवश्यकता है।

उत्तर

45

एमएसडीएन डब्ल्यूपीएफ फ़ोरम पर this conversation के अनुसार (अंतिम पोस्ट देखें) के अनुसार, आप यह देखने के लिए जांच सकते हैं कि IsLoaded गलत है, जिसका अर्थ है कि विंडो अपनी सामग्री को उतारने के लिए "योग्य" है। मुझे उम्मीद है कि आपके लिए काम करता है!

+4

यह गुण एक और धागे से पहुँचा नहीं जा सकता, और असीम निपटाए विंडो ब्लॉक करने के लिए एक कॉल लागू। तो मैं इसके लिए अपने स्वयं के आवृत्ति चर का उपयोग कर समाप्त हुआ और इसे इस तरह से एक्सेस करता हूं जिसमें सिंक्रनाइज़ेशन की आवश्यकता नहीं होती है (ऑनक्लोज्ड विधि की शुरुआत में isClosed = true है, फिर इसे बाद में पढ़ें)। – ygoe

+3

यदि ईवेंट अभी भी संसाधित हो रहा है तो यह काम नहीं करता है।उदाहरण के लिए यदि कोई बटन क्लिक करें हैंडलर विंडो बंद कर देता है और फिर दूसरा खुलता है और दूसरी विंडो की प्रारंभिकता पहले के 'IsLoaded' की जांच करती है, तो यह' सत्य 'वापस आ जाएगी। – nmclean

7

एक और तरीका: Application.Windows में खुली खिड़कियों की एक सूची है। आप जांच सकते हैं कि इस संग्रह में आपकी विंडो है (इसे बंद करने के बाद हटा दिया गया है)।

ऐसा लगता है कि आपको OfType<Window>() पर कॉल करना है क्योंकि यह एक विशेष संग्रह है।

+3

इस से सावधान रहें - इसमें कभी-कभी ऐसी विंडो हो सकती हैं जो बंद नहीं हैं, विशेष रूप से जो खराब XAML –

3

आशा यह आपके लिए उपयोगी है:

PresentationSource.FromVisual (विंडो) == बातिल;

+1

के कारण प्रारंभिक डिस्प्ले के दौरान असफल हो गए थे मेरे लिए काम नहीं किया – user230910

3

मैं क्यों IsDisposed संपत्ति आंतरिक है पता नहीं है, लेकिन अगर आप प्रतिबिंब का डर नहीं:

var window = new Window(); 
var propertyInfo = typeof(Window).GetProperty("IsDisposed", BindingFlags.NonPublic | BindingFlags.Instance); 
var isDisposed = (bool)propertyInfo.GetValue(window); 

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

4

मेरे समाधान केवल संवाद के Closed घटना के लिए एक घटना संलग्न करने के लिए किया गया था:

MikesDialog dlg = new MikesDialog(); 
dlg.Closed += delegate 
{ 
    // The user has closed our dialog. 
    validationgDlg = null; 
}; 

// ...elsewhere in the code... 

if (validationgDlg != null) 
{ 
    // Our "MikesDialog" is still open... 
    . . . 
} 
4

आप विंडो वर्ग से निकाले जाते हैं, तो आप ऐसा कर सकते हैं:

public bool IsClosed { get; private set; } 

protected override void OnClosed(EventArgs e) 
{ 
    base.OnClosed(e); 
    IsClosed = true; 
} 

यह एक फायदा खत्म हो गया है बंद घटना के लिए पंजीकरण - कॉलबैक को अनधिकृत करने की आवश्यकता नहीं है।

0

आप WindowClass bool IsClosed के लिए एक गैर स्थिर संपत्ति जोड़ सकते हैं, और Closed घटना पर सही सेट:

public partial class MyWindow : Window 
{ 
    public bool IsClosed { get; set; } = false; 
    public MyWindow() 
    { 
     Closed += MyWindow_Closed; 
     InitializeComponent(); 
    } 
}  

private void MyWindow_Closed(object sender, EventArgs e) 
{ 
    IsClosed = true; 
} 
संबंधित मुद्दे