Unc*_*aul 6 .net c# wpf windows-7
我有一个非常基本的测试应用程序,只包含a Window
和a CustomControl
.该窗口包含自定义控件,并具有以下附加属性:
TextOptions.TextFormattingMode="Display"
SnapsToDevicePixels="True"
UseLayoutRounding="True"
RenderOptions.EdgeMode="Aliased"
Run Code Online (Sandbox Code Playgroud)
自定义控件将这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));
}
Run Code Online (Sandbox Code Playgroud)
一切都很好.从左上角到右下角对角绘制黑色1px线.完善.不可否认,像素化,但正是我需要的.但是,当我最小化窗口并再次恢复它时,线条变得"模糊".没有在OnRender
窗口恢复后再次调用该方法时会发生这种情况.那么为什么在窗口最小化后绘制的图形会从根本上改变(失去焦点似乎不是问题)?为什么在窗口简单调整大小后一切都恢复正常,我该如何处理这种不需要的行为?每次WindowState
更改看起来有点过分时强制完全调整大小/无效,不是吗?
更新1:
正如@Backlash建议我将自定义控件放在画布中
<Canvas Name="CanvasControl" SizeChanged="FrameworkElement_OnSizeChanged">
<wpfTest:CustomControl x:Name="ChildControl" />
</Canvas>
Run Code Online (Sandbox Code Playgroud)
并处理这样的SizeChanged
事件
private void FrameworkElement_OnSizeChanged(object sender, SizeChangedEventArgs e)
{
ChildControl.Width = CanvasControl.ActualWidth;
ChildControl.Height = CanvasControl.ActualHeight;
}
Run Code Online (Sandbox Code Playgroud)
因为画布内的元素不会自动布局.但是,结果没有改变.
更新2:
掠过我一个想法是听更改窗口状态和强制调整大小-因此一个完整的重绘-窗口及其所有稍微控制改变Width
或Height
窗口的属性:
protected override void OnStateChanged(EventArgs e)
{
if (WindowState != WindowState.Minimized)
{
Width += 1;
}
}
Run Code Online (Sandbox Code Playgroud)
这在某些情况下有效(尽管不是在Window
例如最大化时),但一般来说,出于多种原因,这是一种明显不好的方法.我试图理解在更改大小时可能导致(正确)重绘的原因并且可能与某些事情有关CoreFlags.AreTransformsClean
,但由于所有内容都被声明为内部或私有,我放弃了使用这些标志和任何相关方法.
更新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));
}
Run Code Online (Sandbox Code Playgroud)
至少可以说,"解决方案"很糟糕.这真的很糟糕,但与我迄今为止看到的其他WPF相比,这可能是一种合法的方法.但是,将留下线程以获得一些进一步的答案.
我认为这是因为你正在使用
SnapsToDevicePixels="True"
Run Code Online (Sandbox Code Playgroud)
不幸的是,仅仅调整容器对象的大小并不能保证设备像素对齐。应用程序的整个布局可能会影响图像的对齐方式。每英寸显示点数 (dpi) 也会影响图像对齐。在上面的示例中,仅当显示器设置为 96 点/英寸 (dpi) 时,图像对齐才会起作用。在任何其他设置下,都需要调整布局以适应显示设置。在 Windows Presentation Foundation (WPF) 应用程序中应尽可能避免使用高频图像。
所以尝试将该标志更改为 false 并看看它会做什么
归档时间: |
|
查看次数: |
1472 次 |
最近记录: |