Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Saving FrameworkElement with its DataContext to image file does no succeed

I have a simple UserControl called UserControl1 that contains a TextBlock:

  <UserControl x:Class="WpfApplication2.UserControl1"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
     <Grid>
         <TextBlock Text="{Binding}"/>
     </Grid>
</UserControl>

I initialized a new instance of it and gave it a DataContext in code. when the window is closing I have to draw this control to an image file. The UserControl does not render the bounded text in the file that been created.

enter image description here

and this is my code using the usercontrol:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        Closing += MainWindow_Closing;
    }

    void MainWindow_Closing(object sender, CancelEventArgs e)
    {
        UserControl1 uc = new UserControl1();
        uc.DataContext = "hello";
        uc.Height = 100;
        uc.Width = 100;
        uc.Background = Brushes.LightBlue;
        DrawToImage(uc);
    }

    private void DrawToImage(FrameworkElement element)
    {
        element.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
        element.Arrange(new Rect(element.DesiredSize));

        RenderTargetBitmap bitmap = new RenderTargetBitmap((int)element.Width, (int)element.Height,
                                                           120.0, 120.0, PixelFormats.Pbgra32);
        bitmap.Render(element);

        BitmapEncoder encoder = new PngBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(bitmap));

        using (Stream s = File.OpenWrite(@"C:\555.png"))
        {
            encoder.Save(s);
        }
    }
}

I Hope It's clear enough, any help will be very appreciated.

like image 993
Erez Avatar asked Dec 27 '12 16:12

Erez


1 Answers

You just forgot to force a Layout update on your control after manually Measuring/Arrangeing it (which will not be enough to force binding resolving).

A simple call to UpdateLayout makes it work :

private void DrawToImage(FrameworkElement element)
{
    element.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
    element.Arrange(new Rect(element.DesiredSize));
    element.UpdateLayout();

    RenderTargetBitmap bitmap = new RenderTargetBitmap((int)element.Width, (int)element.Height,
                                                        120.0, 120.0, PixelFormats.Pbgra32);
    bitmap.Render(element);

    BitmapEncoder encoder = new PngBitmapEncoder();
    encoder.Frames.Add(BitmapFrame.Create(bitmap));

    using (Stream s = File.OpenWrite(@"C:\555.png"))
    {
        encoder.Save(s);
    }
}

Edit : More on when bindings are resolved : link

like image 163
Sisyphe Avatar answered Oct 09 '22 14:10

Sisyphe