WPF 以编程方式实例化用户控件以将其呈现为 PNG

标签 wpf controls refresh instantiation

我想在 DLL 中以编程方式实例化用户控件,然后将其保存为 PNG 文件。这对于 PngBitmapEncoder 和 RenderTargetBitmap 一般没有问题。

这是我的问题:

  • 如何实例化该控件?只需使用 new-operator 即可?
  • 我必须在单独的线程中实例化它吗?
  • 如何强制控件更新其所有子控件并再次呈现自身?

这是我的代码,用于实例化用户控件并将其保存为 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 文件只包含图表区域,但没有气泡?为什么?我认为这是一个更新/渲染问题,但如何解决这个问题?

这是 Visual Studio 解决方案,它包含控制台项目,它将用户控件呈现为 PNG 文件以及图表的 WPF 工具包的其他两个项目。

你看一下,它会在exe文件夹下的bin/Debug中分别生成PNG文件:http://www.file-upload.net/download-1904406/ChartRenderBitmap.zip.html

希望它能够正常工作!

谢谢!

最佳答案

图表中的数据不会在 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 以编程方式实例化用户控件以将其呈现为 PNG,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1461382/

相关文章:

c# - 影响 Streamsource 从一个位图到另一个位图不起作用

.net - 我可以在代码隐藏中获取样式的键吗? (WPF)

wpf - 在 Winforms 中托管 WPF 控件

json - 如何使用按钮或拉动刷新来刷新 TableView 和 JSON 数据?

ios - ios中的刷新按钮

c# - 如何在 .NET 中为我的应用程序创建配置文件

c# - 将 ListBox 放入 ScrollViewer : mouse wheel does not work

com - 如何在VB6用户控件中实现高级自定义属性?

c - 为什么禁用带有 WS_CHILD 的父窗口内的编辑控件?

php - 如何将 setInterval 与 mouseenter 结合起来?