2008-10-09 13 views
32

में फ़ॉन्ट डीपीआई को कैसे नियंत्रित करें मैंने छोटे व्यवसाय के लिए एक ऐप बनाया है। कार्यालय में कुछ कर्मचारी सही रूप से फॉर्म नहीं देख सकते हैं। कारण यह है कि उनके पास डीपीआई सेटिंग 96 डीपीआई से ऊपर है। क्या किसी को इसे नियंत्रित करने के तरीके के बारे में पता है?.NET WinForms ऐप

आप सभी के लिए जिनके पास Winforms ऐप्स के साथ अनुभव है, आप अपने फॉर्म लेआउट को कैसे नियंत्रित करते हैं ताकि डीपीआई एप्लिकेशन के स्वरूप को प्रभावित न करे?

+0

संभावित डुप्लिकेट [WinForms कोड कैसे लिखें जो सिस्टम फ़ॉन्ट और डीपीआई सेटिंग्स के लिए स्वत: स्केल करता है?] (Http://stackoverflow.com/questions/22735174/how-to-write-winforms-code-that-auto -स्केल-टू-सिस्टम-फ़ॉन्ट-एंड-डीपीआई-सेटिंग्स) –

+0

आप इस ब्लॉग को इस मामले पर भी जांचते हैं, मुझे लगता है कि यह इस विषय पर अच्छी जानकारी प्रदान करता है: http://www.telerik.com/blogs/winforms -स्केलिंग-एट-डी-डीपीआई-सेटिंग्स-यह-भी-संभव- – checho

उत्तर

16

ऑटोस्केलेमोड को वैश्विक खोज/प्रतिस्थापन के माध्यम से हर जगह इनहेरिट (यानी अपने सभी उपयोगकर्ता नियंत्रण) पर सेट करें, फिर ऑटोस्केल मोड को अपने मुख्य रूप पर डीपीआई पर सेट करें।

मुझे यह भी पता चलता है कि लेआउट कंटेनर इस प्रकार की स्थिति के लिए एंकरों से बेहतर काम करते हैं।

+0

इससे मुझे तीसरे पक्ष के UI टूलकिट के साथ एक ग़लत डीपीआई स्केलिंग स्थिति से निपटने में मदद मिली। धन्यवाद! – pelazem

63

मान लें कि आप उपयोगकर्ता के यूआई फ़ॉन्ट विकल्प (SystemFonts.IconTitleFont) का सम्मान करने की कोशिश नहीं करते हैं, और केवल एक फ़ॉन्ट आकार के लिए अपने फॉर्म हार्ड कोड (जैसे ताहोमा 8pt, माइक्रोसॉफ्ट सैन्स सेरिफ 8.25pt), आप अपना फॉर्म सेट कर सकते हैं AutoScaleMode से ScaleMode.Dpi

यह Form.Scale() है, जो बारी-बारी ही है और सभी बच्चे नियंत्रण पर recursivly संरक्षित ScaleControl() प्रणाली को बुलाती फोन करके कारक CurrentDpiSetting/96 द्वारा प्रपत्र के आकार और इसके बारे में सबसे बच्चे नियंत्रण पैमाने पर होगा। ScaleControl नए स्केलिंग कारक के लिए आवश्यक नियंत्रण की स्थिति, आकार, फ़ॉन्ट इत्यादि को बढ़ाएगा।

चेतावनी: सभी नियंत्रण ठीक से स्वयं को स्केल नहीं करते हैं। सूचीदृश्य के कॉलम, उदाहरण के लिए, व्यापक नहीं होगा क्योंकि फ़ॉन्ट बड़ा हो जाता है। में यह संभालने के लिए कि आपको मैन्युअल रूप से आवश्यक अतिरिक्त स्केलिंग करना होगा। मैं संरक्षित ScaleControl() विधि अधिभावी, और मैन्युअल सूचीदृश्य कॉलम स्केलिंग ऐसा करते हैं:

public class MyForm : Form 
{ 
    protected override void ScaleControl(SizeF factor, BoundsSpecified specified) 
    { 
     base.ScaleControl(factor, specified); 
     Toolkit.ScaleListViewColumns(listView1, factor); 
    } 
} 

public class Toolkit 
{ 
    /// <summary> 
    /// Scale the columns of a listview by the Width scale factor specified in factor 
    /// </summary> 
    /// <param name="listview"></param> 
    /// <param name="factor"></param> 
    /// <example>/* 
    /// protected override void ScaleControl(SizeF factor, BoundsSpecified specified) 
    /// { 
    /// base.ScaleControl(factor, specified); 
    ///  
    /// //ListView columns are not automatically scaled with the ListView, so we 
    /// //must do it manually 
    /// Toolkit.ScaleListViewColumns(lvPermissions, factor); 
    /// } 
    ///</example> 
    public static void ScaleListViewColumns(ListView listview, SizeF factor) 
    { 
     foreach (ColumnHeader column in listview.Columns) 
     { 
      column.Width = (int)Math.Round(column.Width * factor.Width); 
     } 
    } 
} 

यह सब अच्छी तरह से और अच्छा है अगर तुम सिर्फ नियंत्रण का उपयोग कर रहे हैं। लेकिन यदि आप कभी भी किसी भी हार्ड-कोडेड पिक्सेल आकार का उपयोग करते हैं, तो आपको फॉर्म के वर्तमान पैमाने कारक द्वारा अपनी पिक्सेल चौड़ाई और लंबाई को स्केल करने की आवश्यकता होगी। 48x48 को

  • एक 25px उच्च आयत
  • खिंचाव एक आइकन ड्राइंग फार्म पर स्थान (11,56) पर एक छवि ड्राइंग ड्राइंग: स्थितियों कि हार्ड-कोडेड किया जा सकता था पिक्सेल आकार के कुछ उदाहरण
  • ड्राइंग पाठ माइक्रोसॉफ्ट सैंस सेरिफ़ 8.25pt का उपयोग कर
  • एक आइकन के 32x32 प्रारूप हो रही है और एक PictureBox

तो थी में भरने यह मामला है, आपको उन हार्ड-कोडित मानों को "वर्तमान स्केलिंग कारक" से स्केल करने की आवश्यकता होगी। दुर्भाग्य से "वर्तमान" पैमाने पर कारक प्रदान नहीं किया गया है, हमें इसे खुद रिकॉर्ड करने की आवश्यकता है। समाधान यह मानना ​​है कि प्रारंभ में स्केलिंग कारक 1.0 है और हर बार ScaleControl() कहा जाता है, नए कारक द्वारा चलने वाले पैमाने पर कारक को संशोधित करें।

public class MyForm : Form 
{ 
    private SizeF currentScaleFactor = new SizeF(1f, 1f); 

    protected override void ScaleControl(SizeF factor, BoundsSpecified specified) 
    { 
     base.ScaleControl(factor, specified); 

     //Record the running scale factor used 
     this.currentScaleFactor = new SizeF(
     this.currentScaleFactor.Width * factor.Width, 
     this.currentScaleFactor.Height * factor.Height); 

     Toolkit.ScaleListViewColumns(listView1, factor); 
    } 
} 

प्रारंभ में स्केलिंग कारक 1.0 है। प्रपत्र तो 1.25 द्वारा बढ़ाया जाता है, तो स्केलिंग कारक तो हो जाता है: प्रपत्र तो 0.95 द्वारा मापे जाने

1.00 * 1.25 = 1.25 //scaling current factor by 125% 

हैं, तो नई स्केलिंग कारक

1.25 * 0.95 = 1.1875 //scaling current factor by 95% 

कारण एक SizeF प्रयोग किया जाता है (न कि हो जाता है एक फ्लोटिंग पॉइंट वैल्यू से) यह है कि एक्स और वाई दिशाओं में स्केलिंग रकम अलग हो सकती है। यदि कोई फॉर्म ScaleMode.Font पर सेट किया गया है, तो फॉर्म को नए फ़ॉन्ट आकार में स्केल किया गया है। फ़ॉन्ट्स में विभिन्न पहलू अनुपात हो सकते हैं (उदा।सेगो यूआईताहोमा से लंबा फ़ॉन्ट है)। इसका मतलब है कि आपको स्वतंत्र रूप से एक्स और वाई मानों को स्केल करना होगा। यदि आप लेने के लिए जा रहे थे

Point pt = new Point(11, 56); 
control1.Location = pt; 

को
Point pt = new Point(
     (int)Math.Round(11.0*this.scaleFactor.Width), 
     (int)Math.Round(56.0*this.scaleFactor.Height)); 
control1.Location = pt; 

एक ही लागू होता है:

तो अगर आप स्थान (11,56) पर एक नियंत्रण रखने के लिए चाहता था, आप से अपने पोजीशनिंग कोड परिवर्तन होगा एक फ़ॉन्ट आकार:

Font f = new Font("Segoe UI", 8, GraphicsUnit.Point); 

बनना होगा:

Font f = new Font("Segoe UI", 8.0*this.scaleFactor.Width, GraphicsUnit.Point); 

और एक बिटमैप के लिए एक 32x32 आइकन निकालने से बदल जाएगा:

Image i = new Icon(someIcon, new Size(32, 32)).ToBitmap(); 

Image i = new Icon(someIcon, new Size(
    (int)Math.Round(32.0*this.scaleFactor.Width), 
    (int)Math.Round(32.0*this.scaleFactor.Height))).ToBitmap(); 

आदि

सहायक अमानक DPI प्रदर्शनों के लिए एक tax that all developers should pay है। लेकिन तथ्य यह है कि कोई भी नहीं चाहता है क्यों Microsoft gave up and added to Vista the ability for the graphics card to stretch any applications that don't say they properly handle high-dpi

2

मुझे पता है कि यह कुछ हद तक कठोर है, लेकिन WPF में अपने ऐप को फिर से लिखने पर विचार करें। डब्ल्यूपीएफ अनुप्रयोगों की हर डीपीआई सेटिंग पर एक ही नजर है।