7

我有一个名为 UserControl1 的简单 UserControl,其中包含一个 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>

我初始化了它的一个新实例,并在代码中给它一个 DataContext。当窗口关闭时,我必须将此控件绘制到图像文件中。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);
        }
    }
}

我希望它足够清楚,任何帮助将不胜感激。

4

5 回答 5

6

您只是在手动测量/排列控件后忘记强制对控件进行布局更新(这不足以强制绑定解析)。

对UpdateLayout的简单调用使其工作:

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);
    }
}

编辑:有关何时解决绑定的更多信息:链接

于 2012-12-30T12:42:47.290 回答
0

尝试在 userControl1.Loaded 事件上调用函数 SaveImage()

于 2012-12-27T17:02:32.640 回答
0

如果我这样做它会起作用,但不确定这是你想要的:

<Window x:Class="DrawImage.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:DrawImage="clr-namespace:DrawImage"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <DrawImage:UserControl1 x:Name="uc" Visibility="Hidden"/>
    </Grid>
</Window>

void MainWindow_Closing(object sender, CancelEventArgs e)
{
    uc.DataContext = "hello";
    uc.Height = 100;
    uc.Width = 100;
    uc.Background = Brushes.LightBlue;
    uc.Visibility = Visibility.Visible;
    DrawToImage(uc);
}
于 2012-12-30T10:21:00.207 回答
0

编辑

我现在能够重现该问题。如果我在 Window 构造函数中设置 DataContext ,那么它就可以工作。如果我在 Winndow_Closed 事件中设置它,我会得到与你得到的完全相同的结果。

我想可能没有解决方法,因为 WPF 需要一些时间才能在 UI 线程上实际呈现文本。如果在 WPF 在 UI 线程上呈现文本之前呈现 PNG,它将不会出现在 PNG 上。似乎不存在解决方法,因为在Closed事件处理程序运行时窗口将被销毁。一方面,当您希望 UI 线程呈现控件时,无法阻止 UI 线程防止窗口被破坏。

我建议在渲染控件后立即渲染图像,并在关闭窗口时保存图像文件。

于 2012-12-30T10:28:07.707 回答
0

我在我的博客中发布了一篇文章(将 png 透明度放入帐户(导致黑色背景)):将 FrameworkElement 保存为图像

FrameworkElement element = myControl.Content;
// you can set the size as you need.
Size theTargetSize = new Size(1500,2000)
element.Measure(new System.Windows.Size(double.PositiveInfinity, double.PositiveInfinity));
element.Arrange(new Rect(theTargetSize ));
// to affect the changes in the UI, you must call this method at the end to apply the new changes
element.UpdateLayout();

您可以在博客文章中找到完整的鳕鱼。

于 2015-03-02T09:25:48.933 回答