2013-11-26 51 views
6

我們有一個現有的windows .net應用程序,它使用所有自定義控件。使現有的.NET Windows應用程序能夠識別DPI

由於我們只是支持默認的96 dpi分辨率,這些日子過得很好。

既然我們需要我們的應用程序來識別dpi。事情會失控,當我們去到下一個

更高分辨率的120或144等

最常見的問題

  1. 位圖縮放的問題和

  2. 文字截止

通過these之後MSDN文檔d existing SO問題,我試圖

白白合併這樣的修復我的應用程序中(因爲使用的所有控件都

定製,並且不DPI的感知)。

事情修改我application.manifest啓用DPI意識標誌和設置AutoScaleMode到AutoScaleMode.Dpi的主要形式和其他形式的使用如AutoScaleMode繼承

  1. 所變更的控制字體後,我試着在OnLoad事件中

Graphics g = this.CreateGraphics(); int dpi = int.Parse(g.DpiX.ToString());

switch (dpi) 
    { 
     case 125: 
      this.Font = new Font(this.Font.FontFamily, this.Font.Size * 125.0f/(float)(g.DpiX)); 
      Debug.WriteLine("<<---- Selected DPI Resolution :" + " 125 DPI ---->"); 
      break; 
    ... so on 
  • 試圖重寫ScaleControl方法基於DPI
  • 儘量使用不同的縮放因子但是,所有這些似乎從來沒有在我的情況下工作。

    有誰知道/建議我一個更好的方法來解決這個問題。

    感謝

    VATSAG

    +1

    這'int dpi = int.Parse(g.DpiX.ToString());'震動我內心的東西。關於問題,我認爲,你不應該通過交換機檢查DPI。使用公式**總是**,公式應該適用於任何dpi。您可能需要重新佈局佈局,只使用自動調整的'Label'並將它們放在'TableLayoutPanel'內(以保證哪些控件不會重疊)等等。如果在「PictureBox」中,位圖應該沒問題。如果你的意思是你的自定義控件,那麼再次 - 公式+佈局。 – Sinatr

    +0

    對不起,如果我在這裏聽起來很愚蠢......你說這裏的公式是什麼意思? –

    +0

    例如,對於圖像:'new_width = width * scale * old_dpi/new_dpi;'。 – Sinatr

    回答

    6

    所以,我只是有同樣的問題在我的應用程序之一。我設法通過兩個步驟來處理它,不幸的是需要重構一個LOT,但是工作完成後,我設法讓我的應用程序自動縮放到不同的DPI上。這是怎麼一回事呢:

    1. 所有窗體必須設置使用AutoScaleMode = AutoScaleMode.Font規模。當我做了一些挖掘,我發現AutoScaleMode.Dpi並不像預期的那樣工作。你也應該選擇你的標準DPI單位。假設它是96,因爲這是您的應用程序最初設計的反正,那麼您必須將所有表單設置爲AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F)。您可以從設計器視圖中設置這些配置。另外,如果您創建了任何自定義控件,則應將它們全部設置爲使用AutoScaleMode = AsutoScaleMode.Inherit。有了這兩件事,您可以放心,.NET將在您所有的組件上執行所有擴展。

    2. 現在,當它變得棘手。問題是,只要框架沒有動態創建並放置在表單中,該框架就會保持所有控件的大小合適。

    所以,如果你是這樣的:

    var myTextBox = new TextBox(); 
    myTextBox.Location = new System.Drawing.Point(20, 20); 
    myForm.Controls.Add(myTextBox); 
    

    那麼該文本框將被放置在位置(20,20),無論你的DPI是什麼,因此導致它看的地方在高DPI顯示器上。所以解決方案是從不使用硬編碼的像素值,而是使用動態擴展的值,具體取決於您當前的DPI配置。所以,相反你可能需要寫類似:

    var graphics = Graphics.FromHwnd(IntPtr.Zero); // This gets the graphics configuration of the current screen 
    var scaleX = graphics.DpiX/96; // 96 was our standard design DPI, remember? 
    var scaleY = graphics.DpiY/96; 
    var myTextBox = new TextBox(); 
    
    myTextBox.Location = new System.Drawing.Point((int)Math.Round(20 * scaleX), (int)Math.Round(20 * scaleY)); 
    
    myForm.Controls.Add(myTextBox); 
    

    這樣的,你會在屏幕上繪製控件將取決於實際DPI的位置。而且,如果我可能會建議,我實際上會將縮放功能提取到某種助手類中,您可以在其中定義方法來縮放x和y上的值,因此您將擁有標準縮放機制。請注意,在x和y上獨立縮放也很重要,因爲某些屏幕在每個軸上的像素密度不同。不管怎麼說,如果你遵循這兩個條件,你的應用程序應該看起來很好,而不依賴它顯示的屏幕。

    相關問題