繁体   English   中英

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

[英]WPF Application Changes From Monitor To Monitor

我正在编写一个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>

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

  1. 在主窗口大小设置为1920 x 1080的情况下运行您的应用。
  2. 运行您的应用程序,主窗口大小设置为1024 x 576。

当你使用较小的窗口大小运行时,你的矢量图形看起来几乎相同,只是更小,还是它们看起来仍然不同?

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

在没有看到你的XAML的情况下,确切地确定导致不希望的拉伸的原因有点困难,但是既然你提到了矢量图形,我将假设你正在使用诸如PathEllipseRectangle控件。 每个控件都有一个Stretch属性。 我建议你阅读文档中的 Stretch 我猜你应该将Stretch设置为Uniform而不是Fill ,但是你必须尝试确定哪种方法效果最好。

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

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

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

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

您会发现,对于Microsoft Windows屏幕分辨率,无论显示器的大小如何,都默认96dpi 比如我有一个22"在运行监控1080p处,我也可以在同一台电脑连接到我的55"电视机1080p还。 即使22英寸显示器(使用卷尺)在物理上适合与我的55英寸电视尺寸相同的2x2网格,但如果我抓住屏幕,两个显示器的输出位图1920x1080完全相同。

因此,所有显示器都是96dpi ,当你在10英寸平板电脑上使用1920x1080的Retina类型显示时,现在开始出现问题,并且更频繁地在显示设置中提供“使文本和其他项目更大”的设置可以调整远离96dpi可以应对这些情况.WPF应用程序可以正常扩展,但Win32应用程序看起来有点模糊。

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

三种不同解决方案

  1. 在您的1920x1080开发PC上,然后使您的WPF应用程序窗口固定大小为1024x768。 部署的应用程序在Maximised到全屏时会看起来与开发机器完全一样
  <Window x:Class=" ...
    xmlns=" ....
    Width="1024" Height="768" >
    ....
  </Window>
  1. 使用Viewbox环绕所有Viewbox并将Stretch属性设置为UniformToFill 这将允许您的控件报告其大小(在WPF布局过程的Measure阶段),然后统一缩放控件以适合可用的大小。
  <Window x:Class=" ...
   ....

    <Viewbox Stretch="UniformToFill">
       <Grid>
        ....
       </Grid>
    </Viewbox>

  </Window>
  1. 仅缩放屏幕的一部分,留下一些区域(例如按钮的文本),以96dpi渲染。 你可以只用再附上部分显示屏Viewbox或交替使用的下划线功能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;
        }
    }

这里我们在窗口大小发生变化时有一个回调(通过Window类的LayoutUpdated处理程序)。 我们看到窗口的宽度是否小于设计时窗口大小,并且仅适当地缩放Canvas UI元素,而将其他控件缩放到100%。 LayoutTransform可用于大多数WPF UI控件,而不仅仅是Canvas

解决方案2和3提供了缩放,但它们确实有一些副作用,即如果您已经开发了一个图表,其中在两个宽度为1像素的形状之间绘制连接线,那么当缩放比例为1:1时,这将正确呈现但是,抗锯齿导致单像素线在某些情况下显示实心1像素,但在缩放显着不同时会在其他情况下抖动。 有一些高级选项需要大量的研究(例如RenderOptions )和对渲染过程的理解以消除这些影响。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM