WPF应用程序从监视器更改为监视器

时间:2016-01-22 17:32:48

标签: c# wpf vector-graphics

我正在编写一个WPF应用程序,作为工业自动化的GUI。当我的开发机器上运行屏幕分辨率为1920x1080时,它看起来有一定的方式但是当我在我的目标机器1024x768上运行时,它会发生变化。一切都在增长。我认为基于Vector的想法是东西应该保持相同的大小。我通过将显示器直接插入我的开发机器(它是一个触摸屏显示器)排除了计算机(主题设置等)。所以它在我的应用程序或监视器本身中做了不正确的事情

任何想法??

编辑xaml示例

<Controls:MetroWindow x:Class="Trax_HMI.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
    Title="MainWindow" Height="768" Width="1024" WindowStyle="None" WindowState="Maximized" UseNoneWindowStyle="True" ShowTitleBar="False">
    <Grid >

        <Image HorizontalAlignment="Left" Height="559" Margin="10,10,-30,-42" VerticalAlignment="Top" Width="780" Source="Cell Layout.png"/>

        <Button Content="Log Off" HorizontalAlignment="Left" Height="44" Margin="542,10,0,0" VerticalAlignment="Top" Width="132" Click="Button_Click"/>
        <Button Content="Close" HorizontalAlignment="Left" Height="39" Margin="542,59,0,0" VerticalAlignment="Top" Width="132" Click="Button_Click_1"/>
        <Label x:Name="OPCState" HorizontalAlignment="Left" Height="27" Margin="10,10,0,0" VerticalAlignment="Top" Width="217"/>
        <Button Content="Reset" HorizontalAlignment="Left" Height="38" Margin="918,720,0,0" VerticalAlignment="Top" Width="96"/>
     </Grid>
 </Controls:MetroWindow>

3 个答案:

答案 0 :(得分:3)

如果您尝试以下实验会怎样?

  1. 在主窗口大小设置为1920 x 1080的情况下运行您的应用。
  2. 运行您的应用,主窗口大小设置为1024 x 576。
  3. 当您使用较小的窗口大小运行时,您的矢量图形看起来几乎相同,只是更小,或者它们看起来是否仍然不同?

    如果它们看起来几乎相同,只是更小,这意味着您的图形设置为拉伸并填充其父容器。使用1920 x 1080显示器时,宽高比为1920 / 1080 = 1.78。使用1024 x 768显示器时,宽高比为1024 / 768 = 1.33。 (请注意,1024 x 576具有与1920 x 1080相同的宽高比。)由于较小的显示器具有较高的宽高比,因此拉伸以填充容器的图形将显得更高。

    在没有看到你的XAML的情况下,确切地诊断是什么导致了不希望的拉伸有点困难,但是既然你提到了矢量图形,我将假设你正在使用诸如Path之类的控件,{{1 }和Ellipse。这些控件中的每一个都具有Rectangle属性。我建议您阅读documentation中的Stretch。我猜您应该将Stretch设置为Stretch而不是Uniform,但您必须尝试确定最佳效果。

    如果您仍需要帮助,请发布一些显示XAML标记的示例。

答案 1 :(得分:0)

WPF不适用于实际像素。实际上它正在使用DPI设置。显示器的DPI设置是否可能不同?即使在同一台机器上,每个显示器的DPI设置也是唯一的。如果这是问题,this question可能会对您有所帮助。

答案 2 :(得分:0)

我也开发了工业自动化设备,但在我的情况下,我的目标是1080p显示器,但也希望笔记本电脑能够以较低的分辨率(例如1440x900)演示软件。

  

当我的开发机器上运行屏幕分辨率为1920x1080时,它看起来有某种方式但是当我在目标机器1024x768上运行时它会发生变化。一切都在增长。

对于Microsoft Windows屏幕分辨率,无论显示器的大小如何,您都会发现default96dpi。例如,我有一个22&#34;监视器在1080p运行,我也可以将同一台PC连接到我的55&#34;电视1080p也是。即使22&#34;监视器(使用卷尺)物理上适合2x2网格,大小与我的55&#34;相同。电视两个显示器的1920x1080输出位图如果我抓住屏幕就完全一样。

因此,当你在10&#34;平板电脑,更常见的是&#34;使文字和其他项目更大&#34;在显示设置中可以使用这些设置来调整96dpi,以应对这些情况。 WPF应用程序将正确扩展,但Win32应用程序看起来有点模糊。

在您的情况下,96dpi1920x1080都有96dpi,这意味着矢量图形将在两个显示中转换为相同的像素大小。不同之处在于,一台显示器上的最大表单大小仅为1024x768,而另一台显示器上的最大表单大小为1920x1080。如果使用1024x768划分显示,则每个列在较小分辨率显示上的像素较少意味着任何形状(知道两个显示器上的形状将需要相同的像素宽度)使得特定形状占据更多比例专栏。

三种不同的解决方案

  1. 在您的1920x1080开发PC上,然后将WPF应用程序窗口设置为1024x768的固定大小。然后,当Grid全屏显示
  2. 时,您部署的应用程序将与您的开发计算机完全相同
    1920x1080
    1. 使用Maximised对所有控件进行环绕,并将 <Window x:Class=" ... xmlns=" .... Width="1024" Height="768" > .... </Window> 属性设置为Viewbox。这将允许您的控件报告其大小(在WPF布局过程的Stretch阶段),然后统一缩放控件以适应可用的大小。
    2. UniformToFill
      1. 仅缩放屏幕的一部分,使某些区域(例如按钮的文字)呈现在Measure。您只能使用 <Window x:Class=" ... .... <Viewbox Stretch="UniformToFill"> <Grid> .... </Grid> </Viewbox> </Window> 再次显示部分显示内容,或者使用96dpi的下划线功能,该功能可通过Viewbox依赖项属性用于任何控件。
      2. Viewbox

        然后在代码隐藏

        LayoutTransform

        这里我们在窗口大小发生变化时(通过 <Window x:Class=" ... LayoutUpdated="Window_LayoutUpdated" > .... <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="20*"/> <ColumnDefinition Width="60*"/> <ColumnDefinition Width="20*"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="20*"/> <RowDefinition Height="60*"/> <RowDefinition Height="20*"/> </Grid.RowDefinitions> <Canvas Grid.Row="1" Grid.Column="1"> <Canvas.LayoutTransform> <ScaleTransform x:Name="PageScale" ScaleX="1" ScaleY="1"/> </Canvas.LayoutTransform> <Rectangle Width="700" Height="700" Fill="Red"/> </Canvas> </Grid> </Window> 类的 private void Window_LayoutUpdated(object sender, EventArgs e) { if ((ActualWidth != 0) && (ActualWidth < 1900)) { var scale = ActualWidth / 1920.0; PageScale.ScaleX = scale; PageScale.ScaleY = scale; } else { PageScale.ScaleX = 1.0; PageScale.ScaleY = 1.0; } } 处理程序)进行回调。我们看到窗口的宽度是否小于设计时窗口大小,并且仅适当地缩放LayoutUpdated UI元素,而将其他控件缩放到100%。 Window可用于大多数WPF UI控件,而不仅仅是Canvas

        解决方案2&amp; 3提供缩放但它们确实有一些副作用,即如果你开发了一个图表,其中两个形状之间的连接线被绘制,宽度为1像素,那么当缩放比例为1:1时这是正确渲染,但反-aliasing使得单个像素线在某些情况下显示实心1像素,但在缩放显着不同时在其他情况下抖动。有一些高级选项需要大量研究(例如LayoutTransform)以及了解渲染过程以消除这些影响。