简体   繁体   English

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

[英]WPF Application Changes From Monitor To Monitor

I am writing a WPF application to be a GUI for a piece of industrial automation. 我正在编写一个WPF应用程序,作为工业自动化的GUI。 When run on my development machine with a screen resolution on 1920x1080 it looks a certain way but when I run it on my target machine 1024x768 it changes. 当我的开发机器上运行屏幕分辨率为1920x1080时,它看起来有一定的方式但是当我在我的目标机器1024x768上运行时,它会发生变化。 Mostly everything grows. 一切都在增长。 I thought the idea of Vector based is that stuff should remain the same size. 我认为基于Vector的想法是东西应该保持相同的大小。 I have ruled out the computer(Themes settings etc) by plugging the monitor directly into my development machine(It a touch screen monitor). 我通过将显示器直接插入我的开发机器(它是一个触摸屏显示器)排除了计算机(主题设置等)。 So its either something Im doing incorrect in my application or the monitor itself 所以它在我的应用程序或监视器本身中做了不正确的事情

Any ideas?? 有任何想法吗??

Edit xaml sample 编辑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>

What happens if you try the following experiment? 如果您尝试以下实验会怎样?

  1. Run your app with your main window size set to 1920 x 1080. 在主窗口大小设置为1920 x 1080的情况下运行您的应用。
  2. Run your app with your main window size set to 1024 x 576. 运行您的应用程序,主窗口大小设置为1024 x 576。

When you run with the smaller window size, do your vector graphics look pretty much the same, only smaller, or do they still look different? 当你使用较小的窗口大小运行时,你的矢量图形看起来几乎相同,只是更小,还是它们看起来仍然不同?

If they look pretty much the same, only smaller, that means your graphics are set to stretch and fill their parent container. 如果它们看起来几乎相同,只是更小,这意味着您的图形设置为拉伸并填充其父容器。 With a 1920 x 1080 monitor, the aspect ratio is 1920 / 1080 = 1.78 . 使用1920 x 1080显示器时,宽高比为1920 / 1080 = 1.78 With a 1024 x 768 monitor, the aspect ratio is 1024 / 768 = 1.33 . 使用1024 x 768显示器,宽高比为1024 / 768 = 1.33 (Note that 1024 x 576 has the same aspect ratio as 1920 x 1080.) Since the smaller monitor has a taller aspect ratio, graphics stretched to fill the container will appear taller. (请注意,1024 x 576具有与1920 x 1080相同的宽高比。)由于较小的显示器具有较高的宽高比,因此拉伸以填充容器的图形将显得更高。

Without seeing your XAML, it's a little difficult to diagnose exactly what's causing the undesired stretching, but since you mention vector graphics, I'm going to assume you're using controls such as Path , Ellipse , and Rectangle . 在没有看到你的XAML的情况下,确切地确定导致不希望的拉伸的原因有点困难,但是既然你提到了矢量图形,我将假设你正在使用诸如PathEllipseRectangle控件。 Each of these controls has a Stretch property. 每个控件都有一个Stretch属性。 I recommend you read up on Stretch in the documentation . 我建议你阅读文档中的 Stretch I would guess you should be setting Stretch to Uniform rather than Fill , but you will have to experiment to determine exactly what works best. 我猜你应该将Stretch设置为Uniform而不是Fill ,但是你必须尝试确定哪种方法效果最好。

If you still need help, please post some examples showing your XAML markup. 如果您仍需要帮助,请发布一些显示XAML标记的示例。

WPF does not work with actual pixels. WPF不适用于实际像素。 Actually it is using DPI settings. 实际上它正在使用DPI设置。 Is it possible the DPI settings for the displays are different? 显示器的DPI设置是否可能不同? Even on the same machine DPI settings are unique per display. 即使在同一台机器上,每个显示器的DPI设置也是唯一的。 If this is the problem this question might help you further. 如果这是问题, 这个问题可能会对您有所帮助。

I too develop for industrial automation equipment, but in my case I target 1080p displays but also want a laptop to be able to demo the software at a lower resolution (eg 1440x900 ). 我也开发了工业自动化设备,但在我的情况下,我的目标是1080p显示器,但也希望笔记本电脑能够以较低的分辨率(例如1440x900 )演示软件。

When run on my development machine with a screen resolution on 1920x1080 it looks a certain way but when I run it on my target machine 1024x768 it changes. 当我的开发机器上运行屏幕分辨率为1920x1080时,它看起来有一定的方式但是当我在我的目标机器1024x768上运行时,它会发生变化。 Mostly everything grows. 一切都在增长。

What you will find is that for Microsoft Windows screen resolutions all default to 96dpi no matter what size the monitor is. 您会发现,对于Microsoft Windows屏幕分辨率,无论显示器的大小如何,都默认96dpi For example I have a 22" monitor running at 1080p , I can also connect the same PC to my 55" TV at 1080p also. 比如我有一个22"在运行监控1080p处,我也可以在同一台电脑连接到我的55"电视机1080p还。 Even though the 22" monitor (using a tape measure) would physically fit in a 2x2 grid in the same size as my 55" TV the output bitmap of 1920x1080 for the two displays is exactly the same if I took a screen grab. 即使22英寸显示器(使用卷尺)在物理上适合与我的55英寸电视尺寸相同的2x2网格,但如果我抓住屏幕,两个显示器的输出位图1920x1080完全相同。

So all monitors are 96dpi which is now starting to cause problems when you have the Retina type displays of 1920x1080 on a 10" tablet, and more frequently the "Make text and other Items larger" settings are available in the display settings to tweak away from the 96dpi to cope with these situations. WPF applications will scale properly but Win32 apps look a bit fuzzy. 因此,所有显示器都是96dpi ,当你在10英寸平板电脑上使用1920x1080的Retina类型显示时,现在开始出现问题,并且更频繁地在显示设置中提供“使文本和其他项目更大”的设置可以调整远离96dpi可以应对这些情况.WPF应用程序可以正常扩展,但Win32应用程序看起来有点模糊。

In your case you have 96dpi for both 1024x768 and 1920x1080 meaning the vector graphics will translate to the same pixels size on both displays. 在您的情况下, 1024x7681920x1080都有96dpi ,这意味着矢量图形将在两个显示器上转换为相同的像素大小。 The difference being that the maximum form size is only 1024x768 on one monitor and 1920x1080 on the other. 不同之处在于,一台显示器的最大外形尺寸仅为1024x768 ,另一台显示器的最大外形尺寸仅为1920x1080 If you divide the display using a Grid then each column has less pixels on the smaller resolution display meaning any shapes (knowing that the shapes on both monitors will need the same width in pixels) makes a particular shape take more proportion of the column. 如果使用Grid划分显示,则每个列在较小分辨率显示上的像素较少意味着任何形状(知道两个显示器上的形状将需要相同的像素宽度)使得特定形状占据列的更多比例。

Three different Solutions 三种不同解决方案

  1. On your 1920x1080 development PC then make your WPF application window a fixed size of 1024x768. 在您的1920x1080开发PC上,然后使您的WPF应用程序窗口固定大小为1024x768。 Your deployed app will then look exactly like your development machine when it is Maximised to full screen 部署的应用程序在Maximised到全屏时会看起来与开发机器完全一样
  <Window x:Class=" ...
    xmlns=" ....
    Width="1024" Height="768" >
    ....
  </Window>
  1. Surround all controls with a Viewbox and set the Stretch attribute to UniformToFill . 使用Viewbox环绕所有Viewbox并将Stretch属性设置为UniformToFill This will allow your controls to report their size (during the Measure phase of the WPF layout process) and then scale uniformly the controls to fit in the available size. 这将允许您的控件报告其大小(在WPF布局过程的Measure阶段),然后统一缩放控件以适合可用的大小。
  <Window x:Class=" ...
   ....

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

  </Window>
  1. Only scale a proportion of the screen leaving some areas (eg text for buttons) rendering at 96dpi . 仅缩放屏幕的一部分,留下一些区域(例如按钮的文本),以96dpi渲染。 You could only enclose parts of the display again with a Viewbox or alternatively use the underline function of the Viewbox which is available to any control via the LayoutTransform dependency property. 你可以只用再附上部分显示屏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>

Then in the code-behind 然后在代码隐藏

    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;
        }
    }

Here we have a callback when the windows size has changed (via the handler for LayoutUpdated of the Window class). 这里我们在窗口大小发生变化时有一个回调(通过Window类的LayoutUpdated处理程序)。 We see if the width of the window is less than the design time window size and scale appropriately the Canvas UI element only, leaving the other controls scaling to 100%. 我们看到窗口的宽度是否小于设计时窗口大小,并且仅适当地缩放Canvas UI元素,而将其他控件缩放到100%。 LayoutTransform can be used on most WPF UI controls, not just Canvas . LayoutTransform可用于大多数WPF UI控件,而不仅仅是Canvas

Solutions 2 & 3 provide the scaling but they do have some side-effects, namely if you have developed a diagram where a connector line is drawn between two shapes with a width of 1 pixel then this is renders correctly when the scaling is 1:1, but anti-aliasing causes the single pixel line to show solid 1 pixel in some cases but a dithered in others when the scaling is significantly different. 解决方案2和3提供了缩放,但它们确实有一些副作用,即如果您已经开发了一个图表,其中在两个宽度为1像素的形状之间绘制连接线,那么当缩放比例为1:1时,这将正确呈现但是,抗锯齿导致单像素线在某些情况下显示实心1像素,但在缩放显着不同时会在其他情况下抖动。 There are advanced options that require lots of research (eg RenderOptions ) and an understanding of the rendering process to eliminate these effects. 有一些高级选项需要大量的研究(例如RenderOptions )和对渲染过程的理解以消除这些影响。

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

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