gpt4 book ai didi

c# - 为什么最小化和恢复窗口会对 WPF 中已绘制的图形产生影响?

转载 作者:太空狗 更新时间:2023-10-29 22:01:20 25 4
gpt4 key购买 nike

我有一个非常初级的测试应用程序,它只包含一个 Window 和一个 CustomControl。该窗口包含自定义控件并具有以下附加属性:

TextOptions.TextFormattingMode="Display"
SnapsToDevicePixels="True"
UseLayoutRounding="True"
RenderOptions.EdgeMode="Aliased"

自定义控件将这 5 行添加到代码隐藏文件中:

protected override void OnRender(DrawingContext drawingContext)
{
var pen = new Pen(Brushes.Black, 1);
drawingContext.DrawLine(pen, new Point(0, 0), new Point(ActualWidth, ActualHeight));
}

一切正常。从左上角到右下角沿对角线绘制一条 1px 的黑色线。完美的。诚然像素化,但正是我需要的。但是,当我最小化窗口并再次恢复它时,线条变得“模糊”。在恢复窗口后,没有再次调用 OnRender 方法就会发生这种情况。那么为什么在窗口最小化后绘制的图形会发生根本性的变化(失去焦点似乎不是问题)?为什么在简单地调整窗口大小后一切都恢复正常,我该如何处理这种不需要的行为?每次 WindowState 更改时强制完全调整大小/使之无效似乎有点过分,不是吗?

更新 1:

正如@Backlash 建议的那样,我将自定义控件放在 Canvas 中

<Canvas Name="CanvasControl" SizeChanged="FrameworkElement_OnSizeChanged">
<wpfTest:CustomControl x:Name="ChildControl" />
</Canvas>

并像这样处理 SizeChanged 事件

private void FrameworkElement_OnSizeChanged(object sender, SizeChangedEventArgs e)
{
ChildControl.Width = CanvasControl.ActualWidth;
ChildControl.Height = CanvasControl.ActualHeight;
}

因为 Canvas 内的元素不会自动布局。然而,结果并没有改变。

更新 2:

我想到的一个想法是监听窗口状态的变化,并通过稍微改变 Width 来强制调整窗口及其所有控件的大小 - 因此完全重绘>窗口的高度属性:

protected override void OnStateChanged(EventArgs e)
{
if (WindowState != WindowState.Minimized)
{
Width += 1;
}
}

这在某些情况下有效(尽管例如当 Window 最大化时无效),但一般来说,出于多种原因,这是一个明显糟糕的方法。我试图了解是什么原因导致了(正确的)当尺寸改变时重绘,它可能与 CoreFlags.AreTransformsClean 有关,但由于一切都被声明为内部或私有(private),我放弃了使用它们标志和任何相关的方法。

更新 3:

鉴于 WPF 似乎无法直接在屏幕上绘制直线,因此我尝试先绘制到内存中的位图中,然后再将位图绘制到屏幕上。它有效。方法如下:

protected override void OnRender(DrawingContext drawingContext)
{
var rtb = new RenderTargetBitmap((int)ActualWidth, (int)ActualHeight, 96, 96, PixelFormats.Pbgra32);
var line = new Line();
RenderOptions.SetEdgeMode(line, EdgeMode.Aliased);

line.Stroke = Brushes.Black;
line.StrokeThickness = 1;
line.X1 = 0;
line.X2 = ActualWidth;
line.Y1 = 0;
line.Y2 = ActualHeight;
line.Arrange(new Rect(new Size((int)ActualWidth, (int)ActualHeight)));
rtb.Render(line);

drawingContext.DrawImage(rtb, new Rect(0, 0, (int)ActualWidth, (int)ActualHeight));
}

“解决方案”至少可以说是老掉牙了。这真的很糟糕,但与我到目前为止从 WPF 看到的其他方法相比,这可能是一种合法的方法。但是,将让线程保持打开状态以获取更多答案。

最佳答案

我认为这是因为你正在使用

SnapsToDevicePixels="True" 

根据 Microsoft msdn,像素捕捉并不总是准确的

Unfortunately, simply adjusting the container object's size does not guarantee device pixel alignment. The entire layout of an application can have an affect on the alignment of the image. The display dots per inch (dpi) also affects image alignment. In the example above, the image alignment will only work if the display is set to 96 dots per inch (dpi). At any other setting, the layout needs to be adjusted to accommodate the display settings. High frequency images should be avoided whenever possible in Windows Presentation Foundation (WPF) applications.

因此尝试将该标志更改为 false 并查看它的作用

关于c# - 为什么最小化和恢复窗口会对 WPF 中已绘制的图形产生影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14150266/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com