Selberstellte Grafik in WPF

  • WPF

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von GOKTerek.

    Selberstellte Grafik in WPF

    Hallo,

    aktuell bin ich Dabei einen Artikelstamm zu visualisieren, jedoch weiß ich nicht wie ich in WPF umsetzen soll. in Form hätte ich eine Picturebox genommen und dort ein Drawing2D object erstellt.
    Ich habe nun etwas geforscht jedoch weiß ich nicht ob es das richtige ist, deshalb frage ich mal in die runde, wie Ihr das umsetzen würdet.

    Grundelegende Voraussetzung:

    Zoom
    Pan
    Bildexport bzw. Bild als PDF drucken

    Im anhang findet Ihr ein kleines bsp. wie es grundlegend aussehen soll. Es ist nichts kompliziertes.

    Gruß
    Bilder
    • Unbenannt.png

      9,58 kB, 353×295, 145 mal angesehen
    Hallo,

    also kompiliziert ist das nicht wirklich da hast du recht, aber je nachdem wie man das umsetzt kann das durchaus aufwendig werden. Also Drawing wie in Forms ist auch mit WPF möglich, aber doch ein wenig anders. In Wpf würde das so aussehen:

    C#-Quellcode

    1. public class DrawingDisplay : FrameworkElement
    2. {
    3. Pen blackPen2_5 = new Pen(Brushes.Black, 2.5d);
    4. protected override void OnRender(DrawingContext drawingContext)
    5. {
    6. base.OnRender(drawingContext);
    7. double centerX, centerY;
    8. centerX = RenderSize.Width / 2.0d;
    9. centerY = RenderSize.Height / 2.0d;
    10. //Brush(füllung), Pen(Rand), CenterPoint, RadiusX, RadiusY
    11. //Brush darf null sein, Pen darf auch null sein
    12. drawingContext.DrawEllipse(Brushes.Blue, blackPen2_5, new Point(centerX, centerY), centerX * 0.9d, centerY * 0.9d);
    13. drawingContext.DrawEllipse(Brushes.Red, null, new Point(centerX, centerY), centerX * 0.6d, centerY * 0.6d);
    14. drawingContext.DrawEllipse(null, blackPen2_5, new Point(centerX, centerY), centerX * 0.4d, centerY * 0.4d);
    15. }
    16. }

    XML-Quellcode

    1. <Grid>
    2. <local:DrawingDisplay/>
    3. </Grid>


    Es gibt wie immer viele Wege nach Rom. Ich würde den 1. oder 2. von diesen wählen.

    1-> Es werden ja Daten zu den Artikeln und deren Entwicklung schon da sein, diese auslesen und automatisiert malen. Da auch Zoom und Pan erforderlich ist, baut man noch eine Skallierung ein, wie auch ein Offset, dann malt man den sichtbaren Bereich. Zum exportieren als Bild einfach alles in ein Bitmap malen.
    2-> Eigene Framework Elemente anlegen, eins das andere aufnehmen kann(Container, Scrollable), weitere die als Child hinzugefügt werden können, dazu einen visuellen Editor(wie im VisualStudio der Designer). Dann kann man das auch von Hand machen und via Drag&Drag erstellen, dazu haben die Elemente dann weitere Properties die man Im Designer einstellen kann, um die Pfeile darstellen zu können. Z.B. ein Element selektieren, mit einer ComboBox auswahl einstellen mit welchem anderen Element das selektierte "verlinkt" werden soll. Im Parent-Element dann den Export als Bild machen.
    3-> Ein TextFormat entwickeln, mit dem man den Baum beschreibt. Text parsen und dann malen. Dazu könnte man dann auch einen Visuellen editor bauen. So das man mit einem Editor die Textdateien fehlerfrei erstellen kann.
    Zitat von mir 2023:
    Was interessiert mich Rechtschreibung? Der Compiler wird meckern wenn nötig :D

    GOKTerek schrieb:

    (...) in Form hätte ich eine Picturebox genommen und dort ein Drawing2D object erstellt (...)

    Zeichnen in WPF kann man fast genauso vollführen, eigentlich noch viel einfacher bzw. bequemer, weil man sich mit PaintEvents nicht herumplagen muss und die ganzen Rendertransformationen zur Verfügung hat bzw. sich zur Verfügung stellen kann, denn benutzen muss man sie nicht unbedingt - im Netz werden leider oft Dogmen verbreitet, dass es überhaupt nicht gehe, man dies und jenes nicht dürfe und man grundsätzlich umdenken müsse.
    Das gleichzeitige Erscheinen von Dummheit und Unmündigkeit nach Immanuel Kant ist eines der schlimmsten Dinge, die einem Homo sapiens in geistiger Hinsicht widerfahren können, hat manchmal aber auch durchaus seine Vorteile.
    Hallo @DTF und @Gregor Jasinski erstmal danke für eure Hilfe und auch die Erläuterung einer neuen Möglichkeit(@DTF) :) . Ja es gibt wirklich viele Wege. Und ich habe mich auch entschieden. Ich nehme das Image aus WPF, und erstelle temporär ein neues BitmapImage. Die Gründe sind ganz einfach. Ich habe einfache codes für zoom und Pan eines Image Userinterfaces gefunden.

    stackoverflow.com/questions/741956/pan-zoom-image muss ich morgen noch testen ob i.o.

    Die Texte müssen auch nicht Variable sein, sondern kommen alle aus der Datenbank.
    Das Bild habe ich schon, lokal gespeichert(Achtung nur Testcode ;-)).

    VB.NET-Quellcode

    1. Imports System.Drawing
    2. Imports System.Drawing.Drawing2D
    3. Imports GOK_Window_Design.Part_TreeView.My_TRV_PartTree
    4. Public Class Part_Tree_Visualisation
    5. Public Function CreateNewPartTree_Image(New_PartTree_Obj As PartTree_Obj) As Image
    6. 'Dim ObjectLibrary As Dictionary(Of Integer,
    7. End Function
    8. Public Function test() As Image
    9. Dim Test_00 As Graphics
    10. Dim testbmp As New Bitmap(400, 200, System.Drawing.Imaging.PixelFormat.Format32bppArgb)
    11. Test_00 = Graphics.FromImage(testbmp)
    12. Test_00.Clear(Color.Green)
    13. 'Dim testbrush As SolidBrush = New SolidBrush(Color.White)
    14. 'Test_00.FillRectangle(testbrush, 0, 0, 400, 200)
    15. Test_00.DrawRectangle(Pens.Red, 50, 50, 50, 50)
    16. Test_00.DrawRectangle(Pens.Red, 51, 51, 48, 48)
    17. Test_00.DrawRectangle(Pens.Red, 52, 52, 46, 46)
    18. Test_00.DrawRectangle(Pens.Black, 0, 0, 400, 200)
    19. Test_00.DrawRectangle(Pens.Black, 1, 1, 398, 198)
    20. testbmp.Save("C:\Temp\testbild_0010.bmp")
    21. Return testbmp
    22. End Function


    Die größte Problematik ist das das gesamte Projekt Variable ist (aber das macht es ja auch so interessant :) ), also der User entscheidet was angezeigt wird. Hierzu habe ich mir aber evtl. schon eine Lösung überlegt.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „GOKTerek“ ()

    Nur so nebenbei, weil es jeder so machen darf, wie er es für richtig hält oder weil es im Gesamtkontext sonst nicht anders gehen würde - mit Zeichnen in WPF meinte ich eher das hier: learn.microsoft.com/de-de/dotn…w=netframeworkdesktop-4.8

    Man nimmt dann i.d.R. ein Canvas, auf dem die vorher erstellen Shape-Objekte (Linien, Rechtecke, Ellipsen) dann mit Add plaziert werden, mit Graphics hat das dann weniger etwas zu tun. Diese Objekte muss man nicht immer wieder neuzeichnen, man verändert nur deren Eigenschaften und Parameter. Jedes Objekt kann seine eigene RenderTransformationen haben, wenn man das braucht, das gilt auch für Canvas (als Hintergrund) selbst, d.h. man könnte z.B. alles auf einmal um 35° drehen und auf den Faktor 0.75 skalieren - das passiert dann alles automatisch. Sie - die „gezeichneten” Shapes - verursachen keine hässlichen Artefakte auf dem Bildschirm, wenn man sie z.B. animieren möchte, sie verschwinden auch nicht, wenn man z.B. das Fenster minimiert und dann wieder auf den Bildschirm bringt, wie es in WinForms mit den mit Graphics erstellten Formen der Fall war, wenn man z.B. direkt auf der Fläche einer PictureBox selbst statt auf den zugehörigen Layern (Image und BackgroundImage) gezeichnet hat.
    Das gleichzeitige Erscheinen von Dummheit und Unmündigkeit nach Immanuel Kant ist eines der schlimmsten Dinge, die einem Homo sapiens in geistiger Hinsicht widerfahren können, hat manchmal aber auch durchaus seine Vorteile.
    @GOKTerek Ja kann man machen, aber bedenke das System.Drawing.Graphics mit GDI+ rendert. Wenn du schon mit WPF arbeitest, wäre es ratsam mit System.Windows.Media.DrawingContext zu malen, den dieser nutzt DirectX
    zum rendern, was nunmal deutlich besser ist und vor allem schneller. Auch wenn es in diesem Zusammenhang nicht auf jede Nano-Sekunde ankommt.

    Lies dir das mal durch, da werden weitere Unterschiede deutlich.
    leadtools.com/help/sdk/v21/dh/…-between-gdi-and-wpf.html

    Meiner Meinung nach ist das der richtige Weg um in WPF Bilder zu rendern und dann als Datei zu speichern.

    C#-Quellcode

    1. DrawingVisual drawingVisual = new DrawingVisual();
    2. using (DrawingContext drawingContext = drawingVisual.RenderOpen())
    3. {
    4. int width = 800;
    5. int height = 600;
    6. drawingContext.DrawEllipse(Brushes.Red, null, new Point(400d, 300d), 150d, 100d);
    7. drawingContext.Close();
    8. RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Default);
    9. renderTargetBitmap.Render(drawingVisual);
    10. PngBitmapEncoder pngBitmapEncoder = new PngBitmapEncoder();
    11. pngBitmapEncoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap));
    12. using (FileStream fileStream = new FileStream("C:\\users\\nichich\\desktop\\WPF_Image.png", FileMode.Create))
    13. {
    14. pngBitmapEncoder.Save(fileStream);
    15. }
    16. }

    Zitat von mir 2023:
    Was interessiert mich Rechtschreibung? Der Compiler wird meckern wenn nötig :D
    Hallo,

    wie schonmal erwähnt erstmal Danke an euch beide, das Projekt habe ich vor zwei Wochen beendet und die User sind begeistert. Da Sie endlich sehen wo unsere Produkte überall hineinfließen. Sie haben eine Visuelle Darstellung des Projektbaumes, nicht nur Artikel-Nr.!

    @Gregor Jasinski ich werde Canvas für mein nächstes Projekt nutzen, da ich ein ähnliches Projekt zu erstellen habe :) (User war von PartTree begeistert). Mir geht es aber auch nicht die Vorzüge oder Nachteile zu sehen, sondern um zukünftig entscheiden zu können was denn besser ist für das jeweilige Projekt. Jedes Projekt für sich, hat ja seine eigenen Spezifikation, bei dem einen brauchst du nur simple Bilder, bei den anderen musst du Interaktionen(ich hoffe das kann Canvas) mit einbeziehen. Und beide Techniken zu kennen und auch mal angewendet zu haben ist nur von vorteil.

    Anbei ein Bild des Projektes, wobei ich ich nicht alle Informationen eingeblendet habe.
    Bilder
    • PartTree.PNG

      40,16 kB, 1.466×554, 139 mal angesehen
    @ErfinderDesRades einen Treeview haben die Kollegen auch. Aber das reicht nicht für diesen Bedarfsfall, Mit diesem kleinen Bild wird weitergearbeitet. Das Bild das ich bei Post Erstellung mit gesendet habe kommt von einem Kollegen, für das Bild wo ich 5 min. für gebraucht habe(siehe Anhang), hat er 16std. mit manueller Arbeit gebraucht. Und er musste die Daten aus 3 verschiedenen Datenbanken manuell zusammen suchen. All das hat er jetzt in einem Tool, er erledigt jetzt die Arbeit innerhalb von 30min. - 2std. wo er vorher 8-24std.(je nach Artikel Komplexität) gebraucht hat. Mit dem Bild wird auch weitergearbeitet.
    Bilder
    • PartTree.PNG

      176,32 kB, 1.878×982, 133 mal angesehen