2009-09-22 13 views
5

Je veux instancier un contrôle utilisateur par programme dans une DLL pour l'enregistrer ensuite en tant que fichier PNG. Ce n'est généralement pas un problème avec PngBitmapEncoder et RenderTargetBitmap.WPF Instancier Contrôle d'utilisateur par programme pour le rendre au format PNG

Ce sont mes questions:

  • Comment puis-je instanciation du contrôle? Simplement avec le nouvel opérateur?
  • Dois-je l'instancier dans un thread séparé?
  • Comment forcer le contrôle à mettre à jour tous ses enfants et à se rendre à nouveau?

Ceci est mon code pour instancier le contrôle de l'utilisateur et l'enregistrer comme fichier PNG (LetterFrequency est le contrôle de l'utilisateur):

[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 vous exécutez l'application de cette façon, il génère le fichier PNG , mais les données, qui seront ajoutées dans le XAML ne sont pas visibles, si vous regardez dans le concepteur XAML, vous pouvez voir le graphique avec quelques bulles. Le fichier png contient uniquement la zone de graphique, mais pas de bulles? Pourquoi ça? Je pense que c'est un problème de mise à jour/rendu, mais comment résoudre ce problème?

Voici la solution de studio visuel, elle contient le projet de console, qui rend le contrôle de l'utilisateur à un fichier PNG et deux autres projets de la boîte à outils WPF pour le graphique.

Jetez un coup d'oeil, il va générer le fichier PNG dans le répertoire bin/Debug respectivement dans le dossier exe: http://www.file-upload.net/download-1904406/ChartRenderBitmap.zip.html

espoir qu'il fonctionne sans problèmes!

Merci!

Répondre

2

Les données de votre graphique ne sont pas affichées dans votre fichier PNG car une animation est appliquée à la détection des points de données. Jetez un oeil à votre contrôle LetterFrequency dans une fenêtre, et vous verrez les points se révéler progressivement.

Votre code prend un instantané du contrôle immédiatement après sa création, de sorte que vous ne voyez aucune donnée.

Vous pouvez:

  1. envelopper tout cela dans une fenêtre et dire pour prendre l'instantané après X secondes
  2. désactiver toutes les animations dans tous les contrôles que vous allez instantané
  3. peut-être il y a un moyen de animations « avance rapide » programme, mais je ne pouvais pas trouver un

est ici la solution 1, et il fonctionne:

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

Merci pour votre solution intéressante, mais la génération du diagramme doit se faire aussi vite que possible, donc pas d'animation serait le meilleur. Pour remplacer l'animation, j'ai simplement créé un nouveau modèle de contrôle pour le point de données bulle, mais il y a maintenant un autre problème avec l'élément de légende. Jetez un oeil à mon répondeur! –