2013-01-04 31 views
6

Tôi có một ứng dụng thử nghiệm rất thô sơ chỉ bao gồm WindowCustomControl. 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.

+0

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

+0

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

+0

Có thể xem xét lớp Đường dẫn? – Aaj

Trả lời

0

Bạn chỉ có thể làm mất hiệu lực cửa sổ thay vì thay đổi kích thước. Âm thanh như WPF đang cố gắng tránh làm cho bạn vẽ lại cửa sổ - bằng cách (nặng) lưu hình ảnh trên cửa sổ trước khi bạn thu nhỏ nó.

Có lẽ, đó là điều bạn có thể tắt?

-Chert

0

Tự mình làm nên kết quả cuối cùng. Đó có phải là kết xuất mọi thứ bạn không thể làm trong XAML không?

0

Tôi nghĩ rằng đây là bởi vì bạn đang sử dụng

SnapsToDevicePixels="True" 

Pixel chụp không phải luôn luôn chính xác chính xác theo Microsoft msdn

Thật không may, chỉ cần điều chỉnh kích thước đối tượng container không đảm bảo sự liên kết thiết bị điểm ảnh . Toàn bộ bố cục của ứng dụng có thể ảnh hưởng đến căn chỉnh của hình ảnh. Các chấm hiển thị trên mỗi inch (dpi) cũng ảnh hưởng đến căn chỉnh ảnh. Trong ví dụ trên, việc căn chỉnh hình ảnh sẽ chỉ hoạt động nếu màn hình được đặt thành 96 chấm trên mỗi inch (dpi). Ở bất kỳ cài đặt nào khác, bố cục cần được điều chỉnh để phù hợp với cài đặt hiển thị. Nên tránh các hình ảnh tần số cao bất cứ khi nào có thể trong các ứng dụng Windows Presentation Foundation (WPF).

Vì vậy, cố gắng thay đổi lá cờ đó là false và xem những gì nó làm

Các vấn đề liên quan