[英]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? 如果您尝试以下实验会怎样?
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的情况下,确切地确定导致不希望的拉伸的原因有点困难,但是既然你提到了矢量图形,我将假设你正在使用诸如
Path
, Ellipse
和Rectangle
控件。 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. 在您的情况下,
1024x768
和1920x1080
都有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
划分显示,则每个列在较小分辨率显示上的像素较少意味着任何形状(知道两个显示器上的形状将需要相同的像素宽度)使得特定形状占据列的更多比例。
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>
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. Measure
阶段),然后统一缩放控件以适合可用的大小。 <Window x:Class=" ...
....
<Viewbox Stretch="UniformToFill">
<Grid>
....
</Grid>
</Viewbox>
</Window>
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.