2009-07-03 8 views
22

Tôi có đoạn mã sau:Force vẽ của một điều khiển WPF trong bộ nhớ

void Test() 
{ 
    currentImage.Source = GetBitmap(); 
    RenderTargetBitmap rtb = new RenderTargetBitmap(100, 100, 96.0, 96.0, PixelFormats.Default); 
    rtb.Render(currentImage); 
} 

Mã này được cho là để render currentImage, đó là một điều khiển hình ảnh trong XAML của tôi đến một RenderTargetBitmap.

Nó không làm việc, rtb trả về một hình ảnh trống, vấn đề là currentImage không làm cho bản thân chưa và vì vậy hành vi này được mong đợi, tôi nghĩ ...

Để workaround vấn đề này, tôi đã viết này mã:

void Test() 
{ 
    currentImage.Source = GetBitmap(); 

    this.Dispatcher.BeginInvoke((Action)delegate() 
    { 
     RenderTargetBitmap rtb = new RenderTargetBitmap(100, 100, 96.0, 96.0, PixelFormats.Default); 
     rtb.Render(currentImage); 
    }, System.Windows.Threading.DispatcherPriority.Render, null); 

} 

Về cơ bản, tôi đợi hình ảnh hiện tại được hiển thị và sau đó tôi có thể hiển thị nó đúng cách cho RenderTargetBitmap của mình.

Có cách nào để làm cho nó hoạt động mà không sử dụng cách giải quyết này không? Buộc điều khiển hình ảnh hiển thị trong bộ nhớ?

cảm ơn!

+0

Lưu ý: Nếu bạn có bố cục phức tạp và bạn đang hiển thị và ẩn các phần tử với trình chuyển đổi, bạn có thể kết thúc với bố cục cuối cùng không chính xác. Đây là những gì tôi phải làm để làm việc xung quanh nó: http://stackoverflow.com/questions/41966704/wpf-xaml-control-converted-to-an-image-has-incorrect-layout/41966743#41966743 –

Trả lời

38

sử dụng một ViewBox để render trong bộ nhớ

Grid grid = new System.Windows.Controls.Grid() { Background = Brushes.Blue, Width = 200, Height = 200 }; 
Viewbox viewbox = new Viewbox(); 
viewbox.Child = grid; //control to render 
viewbox.Measure(new System.Windows.Size(200, 200)); 
viewbox.Arrange(new Rect(0, 0, 200, 200)); 
viewbox.UpdateLayout(); 
RenderTargetBitmap render = new RenderTargetBitmap(200, 200, 150, 150, PixelFormats.Pbgra32); 
render.Render(viewbox); 
+0

Cảm ơn bạn rất nhiều cho giải pháp này! Tôi đã đấu tranh với điều này trong một thời gian nhưng không biết về thủ thuật ViewBox để render trong bộ nhớ. Cảm ơn bạn!! – Kilhoffer

+7

Điều này sẽ được thị trường như là câu trả lời được chấp nhận! Nó hoạt động hoàn hảo! –

+2

Có thể sử dụng "các thùng chứa" khác (bất kỳ thứ gì xuất phát từ Bảng điều khiển) để đạt được kết quả tương tự. Một ViewBox sẽ mở rộng nội dung trong khi Panels sẽ không. –

8

Tôi nghĩ rằng đây là một BETTER answer.
viewbox không hoạt động hoàn toàn như mong đợi và hóa ra đó là chi phí không cần thiết.

Đây là một bản sao của câu trả lời (thay vì chỉ liên kết)


Bạn cần phải buộc một render của mặt hàng đó, hoặc chờ cho mục để được trả lại. Sau đó, bạn có thể sử dụng các thuộc tính ActualHeightActualWidth.

Để buộc một render:

MenuItem item = new MenuItem(); 
    item.Header = "bling"; 
    item.Icon = someIcon; 
    //Force render 
    item.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity)); 
    item.Arrange(new Rect(item.DesiredSize)); 

Trong ví dụ này MenuItem đã không được đưa ra một chiều cao rõ ràng hoặc chiều rộng. Tuy nhiên, việc buộc render sẽ làm cho nó hiển thị văn bản và biểu tượng tiêu đề được cung cấp.

+0

vâng, cái này làm việc cho tôi ... –