2009-11-16 17 views
9

के साथ काम नहीं कर रहा है अगर मैं SizeToContentWidthAndHeight पर सेट करता हूं, तो WindowStartupLocation="CenterOwner" ठीक से काम नहीं करता है। नई विंडो के केंद्र के बजाय अपने मूल मालिक के केंद्र में रहने के बजाय, यह बच्चे की खिड़की के शीर्ष बाएं कोने की तरह दिखता है जो माता-पिता के केंद्र में होता है। अगर मैं SizeToContent हटा देता हूं तो सब ठीक है। क्या गलत है?wpf center बाल खिड़की sizetocontent

उत्तर

6

जब एक खिड़की

केवल एक चीज मैं तुम्हें भूल जा सकता है कि के बारे में सोच सकते हैं वास्तव में चाइल्ड विंडो जो अपने मालिक है बताने के लिए है दिखाया गया है, इसे मापा जाता है, तो WindowStartupLocation माप प्रक्रिया द्वारा गणना की गई विंडो के ActualWidth और ActualHeight का उपयोग करके संसाधित किया जाता है।

आपके द्वारा वर्णित व्यवहार मुझे बताता है कि ActualWidth और ActualHeight को शो() या ShowDialog() कॉल के समय शून्य या अपेक्षाकृत छोटा माना जाता है और बाद में केवल nonzero मानों पर सेट किया जाता है।

ऐसा हो सकता है, उदाहरण के लिए, विंडो की सामग्री डेटाकॉन्टेक्स्ट का उपयोग करके बनाई गई है जो केवल Loaded ईवेंट पर सेट है। जब Show() कहा जाता है, तो विंडो Loaded नहीं है, इसलिए इसमें कोई डेटा नहीं है। बाद में जब Loaded घटना आग लगती है तो यह डेटाकॉन्टेक्स्ट सेट करता है और विंडो इसकी सामग्री अपडेट करती है लेकिन स्थिति पहले से ही हो चुकी है।

कई अन्य परिदृश्य हैं, उदाहरण के लिए एक डिस्पैचर.बिनिन इनवोक कॉल, या एक अलग थ्रेड, या बाध्यकारी जो देरी या असीमित हैं, का उपयोग करके भरने वाली सामग्री।

मूल रूप से आपको Show() कहा जाता है, और इसे ठीक करने के लिए आपको अपनी खिड़की की सामग्री सामान्य से छोटी होने का कारण बनने की आवश्यकता होती है।

+0

धन्यवाद, मैं वास्तव में शो() के बाद सामग्री को लोड कर रहा था। बेवकूफ गलती, अब ठीक काम करता है :) – immuner

1

आपका प्रश्न थोड़ा अस्पष्ट है। किस विंडो पर ("पैरेंट" या "बच्चा") आप SizeToContent और WindowStartupLocation सेट कर रहे हैं?

यदि मैं अपनी प्रोजेक्ट में दूसरी विंडो बनाता हूं और अपना साइजटॉन्टेंट और विंडोस्टार्टअप लोकेशन सेट करता हूं, तो मुझे वांछित परिणाम मिलते हैं।

Window2 w = new Window2(); 
w.Owner = this; // "this" being the parent window 
w.ShowDialog(); 

या, अधिक संक्षेप:

new Window2 { Owner = this }.ShowDialog(); 
9

ठीक है, रे ने इसे शानदार ढंग से रखा है। सरल शब्दों में, वह क्या कहना चाहता है, कि आप अपने Loaded घटना है, जो रीसेट करता है Height & Width (और यह भी ActualHeight & ActualWidth) के बाद खिड़की की स्थिति से किया जाता है में अपने नियंत्रण की सामग्री की स्थापना कर रहे हैं।

इसे ठीक करने के लिए आपको दो विकल्प हैं:

  1. निर्माता के लिए अपनी सामग्री मूल्य सेटिंग कोड ले जाएँ, या,
  2. एक सरल विधि Owner के अनुसार अपने Window की स्थिति पुनर्गणना के लिए जोड़ें और इस विधि को अपने Loaded ईवेंट के अंत में कॉल करें, इस तरह:

...

private void CenterOwner() 
{ 
    if (Owner != null) 
    { 
     double top = Owner.Top + ((Owner.Height - this.ActualHeight)/2); 
     double left = Owner.Left + ((Owner.Width - this.ActualWidth)/2); 

     this.Top = top < 0 ? 0 : top; 
     this.Left = left < 0 ? 0 : left; 
    } 
} 
2

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

एक चाल है, प्रतीक्षा करने के लिए, कि WPF-queue emtpy है। फिर आप सुनिश्चित हैं कि, डब्ल्यूपीएफ में आपके कोड को संसाधित करने का समय है। इसका मतलब है, आप विंडो के लिए ShowDialog कॉल में देरी करते हैं।

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

 win.Dispatcher.Invoke(new Action(() => win.ShowDialog()), DispatcherPriority.ApplicationIdle); 
संबंधित मुद्दे