2012-09-13 76 views
1

我正在開發WPF應用程序,該應用程序將以全高清液晶屏幕(42英寸)顯示。另外,我需要適應絕對位置的控件。 在開發環境中,我看不到一個長度爲1920x1080的窗口(這是目標屏幕的固定分辨率)。用於LCD屏幕的WPF全高清

完成此任務的最佳做法是什麼?

+0

設計師的左上角有一個縮放欄。你的意思是? –

+0

編號 當應用程序在目標LCD屏幕中啓動(最大化)時,我想保留控件的絕對位置 –

+0

然後您應該爲控件指定絕對位置。顯示一些可視化您的問題的代碼。 –

回答

4

WPF使用與設備無關的單位用於指定寬度/高度/位置/厚度等

1 DIU/DIP =當屏幕DPI被設置爲1個96DPI物理像素.....但1 DIU =當DPI不是96dpi時,物理像素數量不同。

如果您使用Canvas,那麼它使用DIU定位元素。

現在,您意味着您要完全按照像素座標定位。

所以與Canvas做到這一點,無論現在的DPI設置是什麼,你必須使用一個技巧縮放(你可以用一個ViewBox,或者LayoutTransform做到這一點)。

下面的例子顯示了一種實現方法(我的屏幕是1366x768 ....您可以將其更改爲全高清)。

它查看系統的DPI並在DPI上升時獲取Canvas的縮小比例。這使您可以使用真正意味着像素座標的畫布座標。

如果您可以將用戶屏幕更改爲96dpi,則無需執行縮放技巧,因爲1個DIU = 1個96dpi的物理像素...不需要重新縮放。

<Window x:Class="WpfApplication12.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     WindowStyle="None" 
     AllowsTransparency="True" Background="White" 
     SizeToContent="WidthAndHeight" 
     Title="MainWindow" Loaded="Window_Loaded"> 
    <Viewbox x:Name="viewbox"> 
    <Canvas x:Name="canvas"> 
     <Rectangle x:Name="rect" Canvas.Top="10" Canvas.Left="10" Stroke="Red" StrokeThickness="1"/> 
     <Button Canvas.Top="20" Canvas.Left="20">Test Button</Button> 
      <Ellipse Canvas.Top="100" Canvas.Left="100" Width="100" Height="100" Stroke="Red" StrokeThickness="10"/> 
      <TextBlock Canvas.Top="100" Canvas.Left="100" FontSize="15">Some Text</TextBlock> 
     </Canvas> 
    </Viewbox> 
</Window> 

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes; 

namespace WpfApplication12 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     // HD 
     const int screenwidth = 1366; 
     const int screenheight = 768; 

     // FULL HD 
     //const int screenwidth = 1920; 
     //const int screenheight = 1080; 

     public MainWindow() 
     { 
      InitializeComponent(); 

      Top = 0; 
      Left = 0; 

      canvas.Width = screenwidth; 
      canvas.Height = screenheight; 

      rect.Width = screenwidth - 20; 
      rect.Height = screenheight - 20; 
     } 

     private void Window_Loaded(object sender, RoutedEventArgs e) 
     { 
      bool bScaleBackToPixels = true; 

      if (bScaleBackToPixels) 
      { 
       PresentationSource presentationsource = PresentationSource.FromVisual(this); 
       Matrix m = presentationsource.CompositionTarget.TransformToDevice; 

       double DpiWidthFactor = m.M11; 
       double DpiHeightFactor = m.M22; 

       viewbox.Width = screenwidth/DpiWidthFactor; 
       viewbox.Height = screenheight/DpiHeightFactor; 
      } 
      else 
      { 
       viewbox.Width = screenwidth; 
       viewbox.Height = screenheight; 
      } 
     } 
    } 
} 

<Window x:Class="WpfApplication12.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     WindowStyle="None" 
     AllowsTransparency="True" Background="White" 
     SizeToContent="WidthAndHeight" 
     Title="MainWindow" Loaded="Window_Loaded"> 
    <Canvas x:Name="canvas"> 
     <Rectangle x:Name="rect" Canvas.Top="10" Canvas.Left="10" Stroke="Red" StrokeThickness="1"/> 
     <Button Canvas.Top="20" Canvas.Left="20">Test Button</Button> 
      <Ellipse Canvas.Top="100" Canvas.Left="100" Width="100" Height="100" Stroke="Red" StrokeThickness="10"/> 
      <TextBlock Canvas.Top="100" Canvas.Left="100" FontSize="15">Some Text</TextBlock> 
     </Canvas> 
</Window> 

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes; 

namespace WpfApplication12 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     // HD 
     const int screenwidth = 1366; 
     const int screenheight = 768; 

     // FULL HD 
     //const int screenwidth = 1920; 
     //const int screenheight = 1080; 

     public MainWindow() 
     { 
      InitializeComponent(); 

      Top = 0; 
      Left = 0; 

      canvas.Width = screenwidth; 
      canvas.Height = screenheight; 

      rect.Width = screenwidth - 20; 
      rect.Height = screenheight - 20; 
     } 

     private void Window_Loaded(object sender, RoutedEventArgs e) 
     { 
      bool bScaleBackToPixels = true; 

      if (bScaleBackToPixels) 
      { 
       PresentationSource presentationsource = PresentationSource.FromVisual(this); 
       Matrix m = presentationsource.CompositionTarget.TransformToDevice; 

       double DpiWidthFactor = m.M11; 
       double DpiHeightFactor = m.M22; 

       double scalex = 1/DpiWidthFactor; 
       double scaley = 1/DpiHeightFactor; 

       canvas.LayoutTransform = new ScaleTransform(scalex, scaley); 
      } 
     } 
    } 
} 

在96 DPI設置(較小 - 100%)的屏幕看起來像這樣:

enter image description here

在120 DPI設置(中 - 125%)(即, 96 x 1.25 = 120DPI)當使用上面我的ScaleBackToPixels技術時,屏幕看起來像這樣(即它看起來與第一個屏幕相同)。

enter image description here

在120 DPI設置(中 - 125%)(即96 X 1.25 = 120DPI)的屏幕看起來是這樣的,當你根本就不做任何調整(注意圓是如何較大,以及Button的字體和大小)。

enter image description here

所有3張圖片並排比較:

enter image description here

+0

謝謝你的問候答案。 但它不適用於我的情況。我使用全高清(1920x1080)背景的畫布,我的屏幕分辨率爲1366x768。在我的工作機器中,我看不到控件的位置正確。我想我們錯過了一些轉換 (可能是TranslateTransform) –

+1

取消註釋全高清分辨率的這些行... // const int screenwidth = 1920; // const int screenheight = 1080; ....如果你想要一個適當的標題窗口,然後刪除窗口上的WindowStyle =「None」和AllowsTransparency =「True」屬性。 –

+0

我仍然看不到控件 –

0

這裏是一個讓屏幕分辨率1920×1080(FullHD的)在我的筆記本電腦的屏幕分辨率1366×768可見轉型:

XAML

 <ContentControl Canvas.Left="1630" Canvas.Top="400" Content="{Binding Time}" /> 
     <ContentControl Canvas.Left="1630" Canvas.Top="590" Content="{Binding NextPrayTime}" /> 
     <ContentControl Canvas.Left="1650" Canvas.Top="700" Content="{Binding Today}" /> 
     <ContentControl Canvas.Right="520" Canvas.Top="120" Content="{Binding Content}" /> 
     <ContentControl Canvas.Left="0" Canvas.Top="965" Content="{Binding PrayTimes}"> 

     </ContentControl> 
    </Canvas> 
</Viewbox> 

C#

static public class HD 
{ 
    static public float Width { get { return 1366.0f; } } 
    static public float Height { get { return 768.0f; } } 
} 

static public class FHD 
{ 
    static public float Width { get { return 1920.0f; } } 
    static public float Height { get { return 1080.0f; } } 
} 

static public class HDRatios 
{ 
    static public double Width 
    { 
     get 
     { 
#if (DEBUG) 
      return double.Parse((HD.Width/FHD.Width).ToString("0.0")); 
#else 
      return 1; 
#endif 
     } 
    } 
    static public double Height 
    { 
     get 
     { 
#if (DEBUG) 
      return double.Parse((HD.Height/FHD.Height).ToString("0.0")); 
#else 
      return 1; 
#endif 
     } 
    } 

的代碼演示,在開發環境(調試標誌)的改造將自Canvas.Left應用,並在發行版的改造將無法應用Canvas.Top是根據全高清的分辨率。

我希望這種體驗能夠幫助其他人在絕對指標中遇到在WPF中以Canvas顯示控件。