2016-05-27 27 views
4

修飾されたdoubleを使用してサイズを設定するいくつかのコントロールを作成しようとしていますが、コントロールのサイズはどのスクリーンに表示されても同じです。修飾されたdoubleが正しく表示されない

だから私は、資格のある二重二重変換し、このコンバータを内蔵しています:

double effectiveValue = cm; 
string qualifiedDouble = effectiveValue + "cm"; 
LengthConverter lc = new LengthConverter(); 
double converted = (double)lc.ConvertFrom(qualifiedDouble); 

問題は、それが(それが英語で呼ばれていますかIDKのように解決するか、デフォルトのシステムのズームなどのシステムパラメータに関しては本当に効率的ではないということです)

enter image description here

あなたはそうで任意の解像度のための任意の画面上に表示さセンチメートルで正確に同じ値を、任意のズーム設定とを持つことも可能である方法上の任意の手掛かりを持っていますか。それは(主に)動作するはず

おかげ

+2

GUIコンポーネントのサイズを、モニターまで配置されたルーラーによって測定されたセンチメートルにしたい場合は、残念ながら実行できません。 – keith

+1

この場合、修飾されたdoubleの目的は何ですか:Width = "20cm"? @ keith –

+0

WPFは現在のDPI(dots per inch)を使ってcmをピクセルに変換すると思います。主な問題は、コンピュータ画面上のDPIは、プリンタのような物理的な手段ではないということです。 DPIの背後にあるコンピュータディスプレイの歴史を訴える価値があるかもしれません。 – keith

答えて

1

コンピュータに接続されたディスプレイに十分な情報が含まれているEDIDを使用して最終的にそうする方法を見つけました。EDIDは、レジストリに格納されています。

public class CmToPixelConverter : IValueConverter 
{ 
    double ratio = DisplayHelper.GetCmToPixelRatio(); 

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     return (double)value * ratio; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 
:ここ

HKLM\SYSTEM\CurrentControlSet\Enum\\DISPLAY\ + displayId + registryId 

は、私は私のコンバーターを作成したことを使って、画面上のピクセルにCMを変換する割合を取得するためのコード

public static double GetCmToPixelRatio() 
{ 
    var diagVector = GetActiveDisplayDiag(); 

    var width = System.Windows.SystemParameters.PrimaryScreenWidth; 
    return width/diagVector.X; 
} 


public static int GetDPIX() 
{ 
    var dpiXProperty = typeof(SystemParameters).GetProperty("DpiX", BindingFlags.NonPublic | BindingFlags.Static); 

    return (int)dpiXProperty.GetValue(null, null); 

} 

private static Point GetActiveDisplayDiag() 
{ 
    //get active display 
    string wmiQuery = string.Format("Select * from Win32_DesktopMonitor"); 

    ManagementObjectSearcher searcher = new ManagementObjectSearcher(wmiQuery); 
    ManagementObjectCollection retObjectCollection = searcher.Get(); 

    foreach (ManagementObject retObject in retObjectCollection) 
    { 
     try 
     { 
      //get display id 
      string regPath = (string)retObject.GetPropertyValue("PNPDeviceID"); 
      if (regPath != null) 
      { 
       var pathInfo = regPath.Split('\\'); 
       var displayId = pathInfo[1]; 
       RegistryKey reg = Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\Enum\\DISPLAY\\" + displayId); 
       var firstSubReg = reg.GetSubKeyNames()[0]; 
       reg = reg.OpenSubKey(firstSubReg + "\\Device Parameters"); 
       var edid = (byte[])reg.GetValue("EDID"); 
       return new Point(edid[21], edid[22]); 
      } 
     } 
     catch (Exception) { } 
    } 
    return new Point(); 
} 

です

+0

それは面白そうですね!もし可能であれば、いくつかの質問があります。画面とアプリケーションのウィンドウのマッチングを行いますか?つまり、ここでは「ActiveScreen」を使用していますが、アプリケーションのウィンドウが実際の画面にどのように表示されるのでしょうか?私はあなたが "余分な拡張デスクトップスペース"として2番目のモニタを使用していると思うので、私は "アクティブ"はどちらかの画面とウィンドウが他の座って計算をねじるかもしれないと思いますか?ああ、あなたは問題を抱えていますか?つまり、ウィンドウを2番目のモニターにドラッグしたときですか?おそらくそれはすべてOKで間違っていますが、コードが少し単純すぎるように見えます – quetzalcoatl

+0

私のアプリケーションはマルチスクリーンを許可しないコンピュータ上でホストされており、常にフルスクリーンになります。しかし、私はあなたが指摘したことは、Windowsで扱うことができます –

3

は、私は似たものを数回やったが、あなたは、あなたのデスクトップの外観設定(グラフィックカードの設定、プレゼンテーションプロファイルなどでそれを確認する必要があります - あなたがいずれかを持っている場合そのようなソフトウェア)は、すべてのスケーリングが無効になっています(100%普通、大きなフォントなどは設定されていません)。私はそれがあなたが言及した "システムのズーム"だと信じています。

100%に設定すると、すべてのWPFユニットで同じ画面が表示されます。したがって、すべての画面で10x10矩形(または10cmx10cm)が同じに見えるはずです。修飾を使用する場合は、どの解像度でも同じに見えるはずです。理論的に、またはむしろ、OperatingSystemの観点から。

OSが100%確実に計算されているにもかかわらず、カード/モニタの設定によっては、OSの機能について「嘘をついている」ことがあります。あなたは実際のDPIを壁のプロジェクターから手に入れることはできません。 wierdディメンションのモニターの中には、画像を拡大縮小することができ、画像を縦横に歪ませて画面全体を埋めるので、黒の余白がなくなります。あなたのグラフィックスカードのソフトウェアドライバは内部でもそうすることができるので、OSはそれを知りません。また、WPFのDPI、デバイス独立ユニット、および認定長は、システムが知っていることと、実際の画面にどのように関連しているかについてです。

ただし、すべてのシステムスケーリング、画面の塗りつぶし、16:9/4:3の翻訳などが無効になっている場合は、通常は正しく表示されると予想できます。ユーザーがそれを設定することから脱出することはできません。彼らがそれをしたら、あなたのアプリが表示するいくつかの簡単な "定規"画面で結果を確認することができます。それでも間違っているなら、それは主にハードウェアのせいだと思うので、あなたは立ち往生しています。ユーザーが実際に実行したい場合は、変更する必要があります。

btw。私はにコンシェントに "システムズーム"、それはOSのディスプレイの奇妙な部分を処理する方法を見つけていません。最初はレジストリ/ etcの設定を読んでそれに応じてスケールアップ/ダウンすることができますが、OSバージョンが(winXPとwin7のように)異なる場合は、あなたは方法を見つけるだろう、私はしていない。私はちょうど100%に設定するようにユーザーに尋ねた。あるいは、ハードウェアを変更するときは、すでに100%以外の設定をしていたので、ほとんどの場合、gpu/monitorに変わった解像度のスマートなソフトウェアがあることを示していたからです。

+0

あなたの答えquetzalcoatlをありがとう、それは私の問題に部分的に答えますが、それでも助けます。乾杯! –

関連する問題