WPF实例化用户控件编程,以使其作为PNG(WPF Instantiate User control

2019-08-16 15:44发布

我想在一个DLL编程实例化用户控件事后将它保存为PNG文件。 这通常是PngBitmapEncoder和RenderTargetBitmap没有问题。

这是我的问题:

  • 如何实例化控件? 简单地用新的运营商?
  • 难道我必须初始化它在单独的线程?
  • 如何强制控制,以更新其所有的儿童,并再次渲染本身?

这是我的代码来实例化用户控件并保存为PNG文件(LetterFrequency是用户控制):

    [STAThread]
    static void Main(string[] args)
    {
        LetterFrequency let = new LetterFrequency();
        let.Width = 600;
        let.Height = 400;
        let.Background = Brushes.White;

        let.Measure(new Size(let.Width, let.Height));
        let.Arrange(new Rect(new Size(let.Width, let.Height)));

        let.UpdateLayout();

        RenderTargetBitmap bitmap = new RenderTargetBitmap((int)let.Width, (int)let.Height, 96d, 96d, PixelFormats.Pbgra32);
        bitmap.Render(let);

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

        using (Stream stm = File.Create("test.png"))
        {
            png.Save(stm);
        }
    }

如果你运行应用程序这种方式,它生成的PNG文件,但该数据,这将在XAML中添加是不可见的,如果你看看XAML设计器中,您可以看到图表一些气泡。 PNG文件只包含图表区域,但没有泡沫呢? 为什么? 我认为这是一个更新/渲染的问题,但如何解决这个问题?

这里是视觉工作室溶液,它包含了控制台项目,这使得用户控制为PNG文件和WPF工具包图表的其他两个项目。

看看它,它会在EXE文件夹分别生成的bin /调试的PNG文件: http://www.file-upload.net/download-1904406/ChartRenderBitmap.zip.html

希望它的工作原理没有问题!

谢谢!

Answer 1:

图表中的数据在您的PNG文件不会被渲染,因为没有应用到显示数据点的动画。 看看在一个窗口中你LetterFrequency控制,你会看到点逐渐显露出来。

您的代码需要控制的快照创建后立即启动,所以你看不到任何数据。

你可以:

  1. 包装这一切都在一个窗口,并告诉它以X秒后快照
  2. 禁用你要快照的任何控制所有的动画
  3. 也许有一种方法来“快进”的动画编程,但我无法找到一个

这里的解决方案1,和它的工作原理:

    public partial class Window1 : Window
{
    System.Windows.Threading.DispatcherTimer snapshotTimer;

    public Window1()
    {
        InitializeComponent();

        this.Width = 600;
        this.Height = 400;
        let.Width = 600;
        let.Height = 400;
        let.Background = Brushes.White;     

        this.Loaded += new RoutedEventHandler(Window1_Loaded);
    }

    void Window1_Loaded(object sender, RoutedEventArgs e)
    {
        this.snapshotTimer = new System.Windows.Threading.DispatcherTimer();
        this.snapshotTimer.Interval = TimeSpan.FromSeconds(2);
        this.snapshotTimer.Tick += new EventHandler(snapshotTimer_Tick);
        this.snapshotTimer.IsEnabled = true;
    }

    void snapshotTimer_Tick(object sender, EventArgs e)
    {
        this.snapshotTimer.IsEnabled = false;
        WritePng();
    }

    void WritePng()
    {
        RenderTargetBitmap bitmap = new RenderTargetBitmap((int)let.Width, (int)let.Height, 96d, 96d, PixelFormats.Pbgra32);
        bitmap.Render(let);

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

        using (Stream stm = File.Create("test.png"))
        {
            png.Save(stm);
        }

        this.Close();
    }
}


文章来源: WPF Instantiate User control programmatically to render it as PNG