2009-09-22 21 views
5

Quiero crear una instancia de un control de usuario mediante programación en una DLL para guardarlo posteriormente como archivo PNG. Esto generalmente no es un problema con PngBitmapEncoder y RenderTargetBitmap.WPF Crear una instancia del control del usuario mediante programación para representarlo como PNG

Estos son mis preguntas:

  • ¿Cómo crear una instancia del control? Simplemente con el nuevo operador?
  • ¿Tengo que crear una instancia en un hilo separado?
  • ¿Cómo fuerzo el control para actualizar todos sus elementos secundarios y volver a renderizar?

Este es mi código para crear una instancia del control de usuario y guardarlo como PNG-archivo (LetterFrequency es el control de usuario):

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

Si ejecuta la aplicación de esta manera, se genera el archivo PNG , pero los datos, que se agregarán en el XAML no son visibles, si observa el Diseñador de XAML, puede ver el gráfico con algunas burbujas. El archivo png contiene solo el área del gráfico, pero ¿no hay burbujas? ¿Por qué eso? Creo que es un problema de Actualización/renderizado, pero ¿cómo resolver esto?

Aquí está la solución de estudio visual, contiene el Proyecto de consola, que hace que el usuario controle un archivo PNG y otros dos proyectos del kit de herramientas de WPF para el gráfico.

Tener una mirada en ella, que va a generar el archivo PNG en el bin/depuración, respectivamente, en el exe-carpeta: http://www.file-upload.net/download-1904406/ChartRenderBitmap.zip.html

esperar que funcione sin problemas!

Gracias!

Respuesta

2

Los datos en su gráfico no se representan en su archivo PNG porque hay una animación aplicada a la revelación de los puntos de datos. Eche un vistazo a su control LetterFrequency en una ventana y verá que los puntos se revelan gradualmente.

Su código toma una instantánea del control inmediatamente después de su creación, por lo que no ve datos.

Usted podría:

  1. envolver todo esto en una ventana y di a tomar la instantánea después de X segundos
  2. desactivar todas las animaciones en cualquier control que vas a instantánea
  3. tal vez hay una forma de "avanzar rápido" animaciones programáticamente, pero no pude encontrar uno

Aquí es la solución 1, y funciona:

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(); 
    } 
} 
+0

Gracias por su solución interesante, pero la generación de la tabla se debe hacer lo más rápido posible, por lo que hay animación sería el mejor. Para anular la animación, simplemente creé una nueva plantilla de control para el punto de datos de burbuja, pero ahora hay otro problema con el elemento de leyenda. ¡Echa un vistazo a mi respuesta! –

Cuestiones relacionadas