WinForms कोड को कैसे लिखें कि सिस्टम फॉन्ट और डीपीआई सेटिंग्स में ऑटो-स्केल हो?


143

परिचय: वहाँ बहुत सारी टिप्पणियां हैं जो कहती हैं कि "WinForms DPI / फ़ॉन्ट सेटिंग्स के लिए ऑटो-स्केल नहीं करता है; WPF पर स्विच करें।" हालाँकि, मुझे लगता है कि यह .NET 1.1 पर आधारित है; ऐसा लगता है कि उन्होंने वास्तव में .NET 2.0 में ऑटो-स्केलिंग को लागू करने का एक बहुत अच्छा काम किया है। कम से कम अब तक के हमारे शोध और परीक्षण पर आधारित है। हालाँकि, अगर आप में से कुछ लोग बेहतर जानते हैं, तो हम आपसे सुनना पसंद करेंगे। (कृपया बहस करने से परेशान न हों कि हमें WPF पर स्विच करना चाहिए ... यह अभी कोई विकल्प नहीं है।)

प्रशन:

  • WinForms में क्या ठीक से ऑटो-स्केल नहीं करता है और इसलिए इससे बचा जाना चाहिए?

  • WinForms कोड लिखते समय प्रोग्रामर को कौन से डिज़ाइन दिशानिर्देशों का पालन करना चाहिए ताकि यह ऑटो-स्केल पर अच्छी तरह से हो सके?

अब तक हमने जिन डिज़ाइन दिशानिर्देशों की पहचान की है:

देखें समुदाय विकी जवाब नीचे।

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

जवाबों:


127

नियंत्रण जो स्केलिंग का ठीक से समर्थन नहीं करते हैं:

  • Labelसाथ AutoSize = Falseऔर Fontविरासत में मिला है। स्पष्ट रूप Fontसे नियंत्रण पर सेट है इसलिए यह गुण विंडो में बोल्ड दिखाई देता है।
  • ListViewस्तंभ चौड़ाई पैमाने नहीं है। ScaleControlइसके बजाय फ़ॉर्म को ओवरराइड करें । इस जवाब को देखें
  • SplitContainerकी Panel1MinSize, Panel2MinSizeऔर SplitterDistanceगुण
  • TextBoxसाथ MultiLine = Trueऔर Fontविरासत में मिला है। स्पष्ट रूप Fontसे नियंत्रण पर सेट है इसलिए यह गुण विंडो में बोल्ड दिखाई देता है।
  • ToolStripButtonकी छवि। निर्माणकर्ता के रूप में:

    • सेट ToolStrip.AutoSize = False
    • और के ToolStrip.ImageScalingSizeअनुसार सेट करेंCreateGraphics.DpiX.DpiY
    • ToolStrip.AutoSize = Trueजरूरत पड़ने पर सेट करें ।

    कभी -कभी इसे AutoSizeछोड़ा जा सकता है Trueलेकिन कभी-कभी यह उन चरणों के बिना आकार बदलने में विफल रहता है। .NET फ्रेमवर्क 4.5.2 और के साथ परिवर्तन के बिना काम करता है EnableWindowsFormsHighDpiAutoResizing

  • TreeViewके चित्र। और के ImageList.ImageSizeअनुसार सेट करें । के लिए , .NET फ्रेमवर्क 4.5.1 और के साथ परिवर्तन के बिना काम करता है ।CreateGraphics.DpiX.DpiYStateImageListEnableWindowsFormsHighDpiAutoResizing
  • Formका आकार। Formनिर्माण के बाद स्केल निश्चित आकार ।

डिजाइन दिशानिर्देश:

  • सभी कंटेनरकंट्रोल को उसी पर सेट किया जाना चाहिए AutoScaleMode = Font। (फ़ॉन्ट DPI परिवर्तन और सिस्टम फ़ॉन्ट आकार सेटिंग में परिवर्तन दोनों को संभालेगा; DPI केवल DPI परिवर्तन को संभालेगा, सिस्टम फ़ॉन्ट आकार सेटिंग में परिवर्तन नहीं।)

  • AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);96 कंटेनर (अगले बुलेट देखें) और MS Sans Serif के डिफ़ॉल्ट फ़ॉन्ट (बुलेट दो डाउन देखें) को संभालने के साथ ही सभी कंटेनरकंट्रोल भी सेट किए जाने चाहिए । उस डीपीआई के आधार पर डिज़ाइनर द्वारा ऑटो-जोड़ा जाता है जिसे आप डिज़ाइनर में खोलते हैं ... लेकिन हमारी कई पुरानी डिज़ाइनर फ़ाइलों से गायब था। शायद Visual Studio .NET (VS 2005 से पहले का संस्करण) इसे ठीक से नहीं जोड़ रहा था।

  • 96dpi में अपने सभी डिज़ाइनर कार्य करें (हम 120dpi पर स्विच करने में सक्षम हो सकते हैं; लेकिन इंटरनेट पर ज्ञान 96dpi से चिपके रहने के लिए कहता है; प्रयोग वहाँ क्रम में है; डिज़ाइन के अनुसार, इससे कोई फर्क नहीं पड़ता क्योंकि यह सिर्फ AutoScaleDimensionsरेखा को बदलता है; डिजाइनर आवेषण)। एक उच्च-रिज़ॉल्यूशन डिस्प्ले पर वर्चुअल 96 डीपीआई पर चलने के लिए विज़ुअल स्टूडियो सेट करने के लिए, इसकी .exe फ़ाइल, गुणों को संपादित करने के लिए राइट-क्लिक करें, और संगतता के तहत "उच्च डीपीआई स्केलिंग व्यवहार को ओवरराइड करें। स्केलिंग: सिस्टम द्वारा निष्पादित" चुनें।

  • सुनिश्चित करें कि आपने कभी भी कंटेनर स्तर पर फ़ॉन्ट सेट नहीं किया है ... केवल पत्ती नियंत्रण पर या अपने सबसे आधार फॉर्म के निर्माता में यदि आप एमएस सैंस सेरिफ़ के अलावा एक एप्लीकेशन-वाइड डिफ़ॉल्ट फ़ॉन्ट चाहते हैं। (किसी कंटेनर पर फ़ॉन्ट सेट करना उस कंटेनर के ऑटो-स्केलिंग को बंद करने के लिए लगता है क्योंकि यह वर्णानुक्रम में AutoScaleMode और AutoScaleDimensions सेटिंग्स की सेटिंग के बाद आता है।) ध्यान दें कि यदि आप अपने सबसे आधार फॉर्म के निर्माता के फॉन्ट को बदलते हैं, तो यह कारण होगा। आपके AutoScaleDimensions 6x13 से अलग गणना करने के लिए; विशेष रूप से, यदि आप सेगो यूआई (विन 10 डिफ़ॉल्ट फॉन्ट) में बदल जाते हैं, तो यह 7x15 होगा ... आपको डिज़ाइनर में प्रत्येक फॉर्म को छूने की आवश्यकता होगी ताकि यह उस .designer फ़ाइल में सभी आयामों को पुन: जोड़ सके, जिसमें। AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);

  • AnCor का उपयोग न करें Rightया Bottomएक UserControl के लिए लंगर डाले ... इसकी स्थिति ऑटो-स्केल नहीं होगी; इसके बजाय, अपने UserControl में एक पैनल या अन्य कंटेनर को ड्रॉप करें और उस पैनल पर अपने अन्य नियंत्रणों को लंगर डालें; पैनल उपयोग डॉक है Right, Bottomया Fillअपने UserControl में।

  • नियंत्रण सूचियों में केवल नियंत्रण जब ResumeLayoutके अंत में InitializeComponentऑटो बढ़ाया हो जाएगा कहा जाता है ... अगर आप गतिशील रूप से नियंत्रण जोड़ने, तो आप की जरूरत है SuspendLayout(); AutoScaleDimensions = new SizeF(6F, 13F); AutoScaleMode = AutoScaleMode.Font; ResumeLayout();कि नियंत्रण पर इससे पहले कि आप में जोड़ें। और अपने स्थिति भी समायोजित किया जा करने की आवश्यकता होगी यदि आप डॉक मोड या जैसे लेआउट प्रबंधक का उपयोग नहीं कर रहे हैं FlowLayoutPanelया TableLayoutPanel

  • बेस से ली गई बेस क्लास को सेट को ContainerControlछोड़ना चाहिए (क्लास में डिफॉल्ट वैल्यू सेट ; लेकिन डिज़ाइनर द्वारा डिफॉल्ट सेट नहीं)। यदि आप इसे किसी और चीज़ पर सेट करते हैं, और तब आपका व्युत्पन्न वर्ग इसे फॉन्ट (जैसा कि होना चाहिए) में सेट करने की कोशिश करता है, तो सेटिंग का कार्य जो डिजाइनर की सेटिंग को साफ कर देगा , जिसके परिणामस्वरूप वास्तव में ऑटो-स्केलिंग बंद हो जाएगा! (इस गाइडलाइन को पहले वाले के साथ जोड़ दिया गया है जिसका मतलब है कि आप कभी भी किसी डिज़ाइनर में बेस क्लास नहीं कर सकते ... सभी वर्गों को या तो बेस क्लास या लीफ क्लास के रूप में डिज़ाइन करने की ज़रूरत है!)AutoScaleModeInheritContainerControlFontAutoScaleDimensions

  • Form.MaxSizeडिज़ाइनर में सांख्यिकीय रूप से उपयोग करने से बचें । MinSizeऔर MaxSizeफार्म पर उतना नहीं है जितना बाकी सब कुछ। इसलिए, यदि आप अपना सारा काम 96 डीपीआई में करते हैं, तो जब उच्च डीपीआई में आपकी MinSizeसमस्याएं नहीं होंगी, लेकिन आप के लिए जितना संभव हो उतना प्रतिबंधात्मक नहीं हो सकता है, लेकिन MaxSizeआपका आकार सीमित हो सकता है, जो समस्याओं का कारण बन सकता है। यदि आप चाहते हैं MinSize == Size == MaxSize, तो डिज़ाइनर में ऐसा न करें ... अपने निर्माता या OnLoadओवरराइड में ऐसा करें ... दोनों को MinSizeऔर MaxSizeअपने उचित आकार में सेट करें।

  • किसी विशेष पर सभी नियंत्रण Panelया Containerतो एंकरिंग या डॉकिंग का उपयोग करना चाहिए। यदि आप उन्हें मिलाते हैं, तो उसके द्वारा किए गए ऑटो-स्केलिंग Panelअक्सर सूक्ष्म विचित्र तरीकों से दुर्व्यवहार करेंगे।

  • जब यह अपनी ऑटो-स्केलिंग करता है, तो यह समग्र फॉर्म को स्केल करने की कोशिश करेगा ... हालांकि, अगर उस प्रक्रिया में यह स्क्रीन आकार की ऊपरी सीमा में चलता है, तो यह एक कठिन सीमा है जो तब पेंच कर सकती है (क्लिप) स्केलिंग। इसलिए, आपको यह सुनिश्चित करना चाहिए कि डिज़ाइनर में सभी फॉर्म 100% / 96dpi पर 1024x720 से बड़े नहीं हैं (जो कि 1080p स्क्रीन पर 150% से मेल खाते हैं या 300% जो 4K स्क्रीन पर विंडोज की सिफारिश की गई वैल्यू है)। लेकिन आपको विशाल Win10 शीर्षक / कैप्शन बार के लिए घटाना होगा ... इसलिए 1000x680 अधिकतम आकार की तरह ... जो कि डिजाइनर की तरह 994x642 ClientSize होगा। (इसलिए, आप उल्लंघनकर्ताओं को खोजने के लिए ClientSize पर एक FindAll संदर्भ कर सकते हैं।)


NumericUpDownइसके Marginठीक पैमाने पर भी नहीं है। ऐसा लगता है कि मार्जिन दो बार बढ़ाया गया है। अगर मैं इसे एक बार वापस कर दूं, तो यह अच्छा लग रहा है।
13

AutoScaleMode = Fontउन उपयोगकर्ताओं के लिए अच्छा काम नहीं करता है जो एक बहुत बड़े फ़ॉन्ट का उपयोग करते हैं और उबंटू पर। हम पसंद करते हैंAutoScaleMode = DPI
KindDragon

> मल्टीलाइन = ट्रू और फॉन्ट के साथ टेक्स्टबॉक्स विरासत में मिला। सारा दिन पागल हो जाना - यही तय था! बहुत बहुत धन्यवाद! वैसे, वही फिक्स भी लिस्टबॉक्स नियंत्रण के लिए ठीक है। : D
neminem

मेरे लिए, वंशानुगत फ़ॉन्ट के साथ सूची बॉक्स अच्छे पैमाने पर नहीं हैं। वे स्पष्ट रूप से सेट होने के बाद करते हैं। (.NET 4.7)
पल्स जेट

में इस reddit WinForm स्केलिंग समस्या से निपटने धागा मैं इस लिंक मिल गया एक Telerik डेमो मॉनिटर डीपीआई नमूना करने के लिए त्याग मैं इसे अपने आप को उपयोग नहीं किया है। यह
टेलरिक

27

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

यदि आप एक उचित रूप से रीफ़्लोएबल / ऑटो-आकार का लेआउट बनाते हैं, तो लगभग सब कुछ ठीक उसी तरह काम करता है, जैसे कि विज़ुअल स्टूडियो द्वारा उपयोग की जाने वाली डिफ़ॉल्ट सेटिंग्स के साथ, स्वचालित रूप से, (मूल रूप में AutoSizeMode = Font, और बाकी सब चीज़ों पर इनहेरिट)।

एकमात्र गोचा है यदि आपने डिज़ाइनर में फ़ॉर्म पर फ़ॉन्ट संपत्ति सेट की है। उत्पन्न कोड वर्णानुक्रम में वर्णानुक्रम में छाँटेगा, जिसका अर्थ है कि पहलेAutoScaleDimensions असाइन किया जाएगा । दुर्भाग्य से, यह पूरी तरह से WinForms ऑटो स्केलिंग लॉजिक को तोड़ता है। Font

हालांकि फिक्स सरल है। या तो Fontडिज़ाइनर में प्रॉपर्टी को बिल्कुल सेट न करें (इसे अपने फॉर्म कंस्ट्रक्टर में सेट करें), या मैन्युअल रूप से इन असाइनमेंट को फिर से करें (लेकिन फिर आपको डिज़ाइनर में फॉर्म को एडिट करने के लिए हर बार ऐसा करते रहना होगा)। Voila, न्यूनतम परेशानी के साथ लगभग सही और पूरी तरह से स्वचालित स्केलिंग। यहां तक ​​कि फार्म के आकार को सही ढंग से बढ़ाया जाता है।


जब मैं उनका सामना करूंगा, मैं यहां ज्ञात समस्याओं को सूचीबद्ध करूंगा:


1
Fontडिजाइनर में सेट न करना : एक विचार मन में आता है: आगे बढ़ें और डिजाइनर में फ़ॉन्ट सेट करें, ताकि आप वांछित फ़ॉन्ट के साथ डिजाइन कर सकें। कंस्ट्रक्टर में, लेआउट के बाद, उस प्रॉपर्टी को पढ़ें और उसी मूल्य को फिर से सेट करें? या शायद लेआउट को फिर से करने के लिए कहें? [चेतावनी: मेरे पास इस दृष्टिकोण का परीक्षण करने का कारण नहीं है।] या प्रति नॉलेज के जवाब के अनुसार , पिक्सेल में डिज़ाइनर निर्दिष्ट में (इसलिए विज़ुअल स्टूडियो डिज़ाइनर उच्च डीपीआई मॉनिटर पर पुनर्विक्रय नहीं करेगा), और कोड में उस मान को पढ़ें, पिक्सेल से कनवर्ट करें बिंदुओं के लिए (सही स्केलिंग प्राप्त करने के लिए)।
टूलमेकरसैट

1
हमारे कोड के हर एक बिट में ऑटो स्केल मोड से ठीक पहले ऑटो स्केल आयाम होते हैं और यह पूरी तरह से मापता है। आदेश की तरह लगता है ज्यादातर मामलों में कोई फर्क नहीं पड़ता।
जोश

मैंने अपने कोड को ऐसे उदाहरणों के लिए खोजा जहां शीर्ष उत्तर में अनुशंसित के AutoScaleDimensionsअनुसार सेट नहीं किया गया था new SizeF(6F, 13F)। यह पता चला कि प्रत्येक उदाहरण में, फ़ॉर्म की फ़ॉन्ट संपत्ति सेट की गई थी (डिफ़ॉल्ट नहीं)। ऐसा प्रतीत होता है कि जब AutoScaleMode = Font, तब AutoScaleDimensionsफॉर्म की फ़ॉन्ट संपत्ति के आधार पर गणना की जाती है। इसके अलावा, विंडोज कंट्रोल पैनल में स्केलिंग सेटिंग का प्रभाव पड़ता है । AutoScaleDimensions
वाल्टर स्टबोसज़

24

.Net फ्रेमवर्क 4.7 के लिए अपने एप्लिकेशन को लक्षित करें और इसे विंडोज 10 v1703 (क्रिएटर्स अपडेट बिल्ड 15063) के तहत चलाएं। Windows 10 (v1703) के तहत .Net 4.7 के साथ , MS ने DPI में बहुत सुधार किया

.NET फ्रेमवर्क 4.7 के साथ शुरू, विंडोज फॉर्म में सामान्य उच्च डीपीआई और गतिशील डीपीआई परिदृश्यों के लिए एन्हांसमेंट शामिल हैं। इसमें शामिल है:

  • कई Windows प्रपत्र नियंत्रणों के स्केलिंग और लेआउट में सुधार, जैसे कि मंकेलेन्डर नियंत्रण और चेकडेलबॉक्स नियंत्रण।

  • एकल पास स्केलिंग। .NET फ्रेमवर्क 4.6 और पुराने संस्करणों में, स्केलिंग को कई पास के माध्यम से किया गया था, जिससे कुछ नियंत्रणों को आवश्यक से अधिक स्केल किया गया था।

  • डायनेमिक DPI परिदृश्यों के लिए समर्थन जिसमें उपयोगकर्ता Windows प्रपत्र अनुप्रयोग लॉन्च करने के बाद DPI या स्केल फैक्टर को बदलता है।

इसका समर्थन करने के लिए, अपने एप्लिकेशन में एक एप्लिकेशन मैनिफ़ेस्ट जोड़ें और संकेत दें कि आपका ऐप विंडोज़ 10 का समर्थन करता है:

<compatibility xmlns="urn:schemas-microsoft.comn:compatibility.v1">
    <application>
        <!-- Windows 10 compatibility -->
        <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
    </application>
</compatibility>

इसके बाद, एक जोड़ें app.configऔर एप्लिकेशन को मॉनिटर मॉनिटर अवेयर घोषित करें। यह अब app.config में किया गया है और पहले की तरह प्रकट में नहीं है!

<System.Windows.Forms.ApplicationConfigurationSection>
   <add key="DpiAwareness" value="PerMonitorV2" />
</System.Windows.Forms.ApplicationConfigurationSection> 

यह PerMonitorV2 विंडोज 10 क्रिएटर्स अपडेट के बाद से नया है:

DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2

प्रति मॉनिटर v2 के रूप में भी जाना जाता है। मूल प्रति-मॉनिटर डीपीआई जागरूकता मोड पर एक उन्नति, जो अनुप्रयोगों को प्रति शीर्ष-स्तरीय विंडो आधार पर नए डीपीआई-संबंधित स्केलिंग व्यवहार तक पहुंचने में सक्षम बनाता है।

  • चाइल्ड विंडो डीपीआई परिवर्तन सूचनाएँ - प्रति मॉनिटर v2 संदर्भों में, पूरे विंडो ट्री को होने वाले किसी भी डीपीआई परिवर्तन के बारे में सूचित किया जाता है।

  • गैर-क्लाइंट क्षेत्र का स्केलिंग - सभी विंडो स्वचालित रूप से अपने गैर-क्लाइंट क्षेत्र को एक डीपीआई संवेदनशील फैशन में खींचा जाएगा। EnableNonClientDpiScaling की कॉल अनावश्यक हैं।

  • Win32 मेनू के एस कैलिंग - प्रति मॉनिटर v2 संदर्भों में बनाए गए सभी NTUSER मेनू प्रति मॉनिटर फैशन में स्केलिंग होंगे।

  • डायलॉग स्केलिंग - प्रति मॉनिटर v2 संदर्भों में बनाए गए Win32 संवाद स्वचालित रूप से DPI परिवर्तनों का जवाब देंगे।

  • Comctl32 नियंत्रण की बेहतर स्केलिंग - विभिन्न comctl32 नियंत्रणों ने प्रति मॉनिटर v2 संदर्भों में DPI स्केलिंग व्यवहार में सुधार किया है।

  • बेहतर थीमिंग व्यवहार - प्रति मॉनिटर v2 विंडो के संदर्भ में खोला गया UxTheme हैंडल उस विंडो से जुड़े DPI के संदर्भ में काम करेगा।

अब आप DPI परिवर्तनों के बारे में सूचित करने के लिए 3 नई घटनाओं की सदस्यता ले सकते हैं:

  • Control.DpiChangedAfterParent , जो तब निकाल दिया जाता है जब नियंत्रण के लिए DPI सेटिंग प्रोग्रामेटिक रूप से बदल दी जाती है, जब DPI परिवर्तन ईवेंट के लिए यह पेरेंट कंट्रोल या फॉर्म होता है।

  • Control.DpiChangedBeforeParent , जो कि नियंत्रण के लिए DPI सेटिंग को उसके मूल नियंत्रण या प्रपत्र के लिए DPI परिवर्तन ईवेंट से पहले प्रोग्रामेटिक रूप से बदल दिया जाता है, जब निकाल दिया जाता है।

  • Form.DpiChanged , जिसे निकाल दिया जाता है जब DPI सेटिंग डिस्प्ले डिवाइस पर बदलता है जहां वर्तमान में फॉर्म प्रदर्शित होता है।

आपके पास DPI हैंडलिंग / स्केलिंग के बारे में 3 सहायक विधियाँ हैं:

  • Control.LogicalToDeviceUnits , जो तार्किक से डिवाइस पिक्सेल तक के मान को परिवर्तित करता है।

  • Control.ScaleBitmapLogicalToDevice , जो डिवाइस के लिए तार्किक DPI के लिए एक बिटमैप छवि को मापता है।

  • नियंत्रण। DeviceDpi , जो वर्तमान डिवाइस के लिए DPI लौटाता है।

यदि आप अभी भी समस्याएं देखते हैं, तो आप app.config प्रविष्टियों के माध्यम से DPI में सुधार का विकल्प चुन सकते हैं

यदि आपके पास स्रोत कोड तक पहुंच नहीं है, तो आप विंडोज एक्सप्लोरर में एप्लिकेशन प्रॉपर्टीज पर जा सकते हैं, संगतता पर जा सकते हैं और चयन कर सकते हैं System (Enhanced)

यहां छवि विवरण दर्ज करें

जो GDI स्केलिंग को सक्रिय करता है, वह DPI हैंडलिंग को भी बेहतर बनाता है:

उन अनुप्रयोगों के लिए जो GDI- आधारित विंडोज हैं, अब प्रति मॉनिटर के आधार पर इन्हें DPI स्केल कर सकते हैं। इसका अर्थ है कि ये अनुप्रयोग, जादुई रूप से, डीपीआई की निगरानी के प्रति जागरूक हो जाएंगे।

उन सभी चरणों को करें और आपको WinForms अनुप्रयोगों के लिए एक बेहतर DPI अनुभव प्राप्त करना चाहिए। लेकिन याद रखें, आपको अपने ऐप को .net 4.7 के लिए टारगेट करना होगा और कम से कम विंडोज 10 बिल्ड 15063 (क्रिएटर्स अपडेट) की जरूरत होगी। अगले विंडोज 10 अपडेट 1709 में, हमें अधिक सुधार मिल सकते हैं।


12

एक गाइड जो मैंने काम पर लिखा था:

WPF 'डिवाइस इंडिपेंडेंट यूनिट्स' में काम करता है, जिसका मतलब है कि सभी नियंत्रण उच्च डीपीआई स्क्रीन पर पूरी तरह से लागू होते हैं। WinForms में, यह अधिक ध्यान रखता है।

WinForms पिक्सल में काम करता है। सिस्टम डीपीआई के अनुसार टेक्स्ट को स्केल किया जाएगा लेकिन यह अक्सर एक अनकल्ड कंट्रोल से क्रॉप हो जाएगा। ऐसी समस्याओं से बचने के लिए, आपको स्पष्ट आकार और स्थिति से बचना चाहिए। इन नियमों का पालन करें:

  1. जहाँ भी आपको यह (लेबल, बटन, पैनल) मिलें, AutoSize प्रॉपर्टी को True पर सेट करें।
  2. लेआउट के लिए, वेनिला पैनल की बजाए लेआउट के लिए FlowLayoutPanel (a la WPF StackPanel) और TableLayoutPanel (एक ला WPF ग्रिड) का उपयोग करें।
  3. यदि आप एक उच्च डीपीआई मशीन पर विकसित कर रहे हैं, तो विजुअल स्टूडियो डिजाइनर एक हताशा हो सकता है। जब आप AutoSize = True सेट करते हैं, तो यह आपकी स्क्रीन पर नियंत्रण का आकार बदल देगा। यदि नियंत्रण में AutoSizeMode = GrowOnly है, तो यह सामान्य डीपीआई पर लोगों के लिए इस आकार का रहेगा, अर्थात। उम्मीद से बड़ा होना। इसे ठीक करने के लिए, सामान्य डीपीआई वाले कंप्यूटर पर डिजाइनर खोलें और राइट-क्लिक करें, रीसेट करें।

3
उन संवादों के लिए जिन्हें सब कुछ पर स्वचलित आकार दिया जा सकता है एक दुःस्वप्न होगा, मैं नहीं चाहता कि मेरे बटन बड़े और छोटे हो जाएं क्योंकि मैं प्रोग्राम चलाते समय अपने संवादों का आकार मैन्युअल रूप से बढ़ाता हूं।
जोश

10

मुझे लगा कि WinForms को उच्च डीपीआई के साथ अच्छा खेलना बहुत मुश्किल होगा। इसलिए, मैंने प्रपत्र व्यवहार को ओवरराइड करने के लिए एक VB.NET विधि लिखी है:

Public Shared Sub ScaleForm(WindowsForm As System.Windows.Forms.Form)
    Using g As System.Drawing.Graphics = WindowsForm.CreateGraphics
        Dim sngScaleFactor As Single = 1
        Dim sngFontFactor As Single = 1
        If g.DpiX > 96 Then
            sngScaleFactor = g.DpiX / 96
            'sngFontFactor = 96 / g.DpiY
        End If
        If WindowsForm.AutoScaleDimensions = WindowsForm.CurrentAutoScaleDimensions Then
            'ucWindowsFormHost.ScaleControl(WindowsForm, sngFontFactor)
            WindowsForm.Scale(sngScaleFactor)
        End If
    End Using
End Sub

6

मैं हाल ही में इस समस्या को लेकर आया था, विशेषकर विजुअल स्टूडियो के साथ संयोजन में जब संपादक को उच्च-डीपीआई प्रणाली पर खोला जाता है। मुझे इसे रखना सबसे अच्छा लगा AutoScaleMode = Font, लेकिन डिफ़ॉल्ट फ़ॉन्ट के लिए फ़ॉर्म फ़ॉन्ट सेट करना , लेकिन पिक्सेल में आकार निर्दिष्ट करना , बिंदु नहीं, अर्थात Font = MS Sans; 11px:। कोड में, मैं फिर फ़ॉन्ट को डिफ़ॉल्ट पर रीसेट करता हूं : Font = SystemFonts.DefaultFontऔर सब ठीक है।

केवल मेरे दो सेंट्स। मैंने सोचा था कि मैं साझा करता हूं, क्योंकि "AutoScaleMode = Font" , और "डिज़ाइनर के लिए पिक्सेल में सेट फ़ॉन्ट आकार" कुछ ऐसा था जो मुझे इंटरनेट पर नहीं मिला।

मेरे ब्लॉग पर मेरे कुछ और विवरण हैं: http://www.sgrottel.de/?p=1581&lang=en


4

एंकरों के अलावा बहुत अच्छा काम नहीं कर रहा है: मैं एक कदम आगे बढ़ूंगा और कहूंगा कि सटीक स्थिति (उर्फ, स्थान संपत्ति का उपयोग करके) फ़ॉन्ट स्केलिंग के साथ बहुत अच्छी तरह से काम नहीं करता है। मुझे इस मुद्दे को दो अलग-अलग परियोजनाओं में संबोधित करना है। उन दोनों में, हमें TableLayoutPanel और FlowLayoutPanel का उपयोग करके सभी WinForms नियंत्रणों की स्थिति को बदलना पड़ा। TableLayoutPanel के अंदर डॉक (आमतौर पर भरने के लिए सेट) संपत्ति का उपयोग करना बहुत अच्छी तरह से काम करता है और सिस्टम डीपीआई के साथ ठीक करता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.