Tôi có một ứng dụng thử nghiệm rất thô sơ chỉ bao gồm Window
và CustomControl
. Cửa sổ chứa các điều khiển tùy chỉnh và có các thuộc tính bổ sung sau đây:Tại sao việc thu nhỏ và khôi phục cửa sổ có ảnh hưởng đến đồ họa đã vẽ trong WPF?
TextOptions.TextFormattingMode="Display"
SnapsToDevicePixels="True"
UseLayoutRounding="True"
RenderOptions.EdgeMode="Aliased"
các điều khiển tùy chỉnh có những 5 dòng thêm vào tập tin code-behind:
protected override void OnRender(DrawingContext drawingContext)
{
var pen = new Pen(Brushes.Black, 1);
drawingContext.DrawLine(pen, new Point(0, 0), new Point(ActualWidth, ActualHeight));
}
Tất cả mọi thứ hoạt động tốt. Đường màu đen 1px được vẽ theo đường chéo từ góc trên bên trái đến góc dưới cùng bên phải. Hoàn hảo. Phải thừa nhận pixelated, nhưng chính xác những gì tôi cần. Tuy nhiên, khi tôi thu nhỏ cửa sổ và khôi phục lại, dòng này bị "mờ". Điều này xảy ra khi không có phương thức OnRender
được gọi lại sau khi cửa sổ đã được khôi phục. Vậy tại sao vẽ đồ họa về cơ bản thay đổi sau khi cửa sổ được giảm thiểu (mất tập trung dường như không phải là vấn đề)? Tại sao mọi thứ trở lại bình thường sau khi cửa sổ được thay đổi kích thước đơn giản và làm cách nào tôi có thể xử lý hành vi không mong muốn này? Buộc thay đổi kích thước/vô hiệu hóa hoàn toàn mỗi lần các thay đổi WindowState
có vẻ hơi quá mức, phải không?
Cập nhật 1:
Như @Backlash đề nghị tôi đặt điều khiển tùy chỉnh bên trong một canvas
<Canvas Name="CanvasControl" SizeChanged="FrameworkElement_OnSizeChanged">
<wpfTest:CustomControl x:Name="ChildControl" />
</Canvas>
và xử lý các sự kiện như thế này SizeChanged
private void FrameworkElement_OnSizeChanged(object sender, SizeChangedEventArgs e)
{
ChildControl.Width = CanvasControl.ActualWidth;
ChildControl.Height = CanvasControl.ActualHeight;
}
từ các yếu tố bên trong một canvas không được bố trí tự động. Tuy nhiên, kết quả không thay đổi.
Cập nhật 2:
Một ý tưởng rằng vượt qua tâm trí của tôi đã được nghe những thay đổi trạng thái cửa sổ và buộc một thay đổi kích thước - và do đó một vẽ lại hoàn toàn - các cửa sổ và tất cả các điều khiển của mình bằng một chút thay đổi Width
hoặc Height
tài sản của cửa sổ:
protected override void OnStateChanged(EventArgs e)
{
if (WindowState != WindowState.Minimized)
{
Width += 1;
}
}
này hoạt động trong một số trường hợp (mặc dù không phải khi Window
là tối đa chẳng hạn), nhưng nói chung đây là một cách tiếp cận trắng trợn xấu đối với một số lý do. Tôi đã cố gắng hiểu những gì gây ra một (chính xác) vẽ lại khi kích thước được thay đổi và nó có thể có một cái gì đó để làm với CoreFlags.AreTransformsClean
, nhưng kể từ khi tất cả mọi thứ hoặc là tuyên bố nội bộ hoặc privat tôi đã từ bỏ việc sử dụng những lá cờ và bất kỳ phương pháp liên quan.
Cập nhật 3:
Cho rằng WPF dường như bị bất lực quá tải với vẽ đường thẳng trực tiếp trên màn hình, tôi đã cố gắng vẽ vào một bitmap trong-bộ nhớ đầu tiên và hơn vẽ bitmap lên màn hình. Và nó hoạt động. Đây là phương pháp:
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));
}
"Giải pháp" là ít nhất để nói. Nó thực sự xấu, nhưng so với phần còn lại tôi đã thấy cho đến nay từ WPF này có thể là một cách tiếp cận legit. Tuy nhiên, sẽ để lại chuỗi mở cho một số câu trả lời khác.
Ra khỏi tò mò, những gì sẽ xảy ra nếu bạn đặt điều khiển tùy chỉnh bên trong một container Canvas thay vì trực tiếp trên cửa sổ? – Backlash
Tôi đã thử, nhưng tiếc là kết quả không thay đổi. Dòng vẫn bị mờ sau khi khôi phục cửa sổ từ trạng thái thu nhỏ. – UnclePaul
Có thể xem xét lớp Đường dẫn? – Aaj