Page Index Toggle Pages: [1] 2  Send TopicPrint
Hot Topic (More than 10 Replies) How do you turn a DiagramView into a Bitmap? (Read 1037 times)
koichi_satoh
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 25
Joined: Nov 30th, 2023
How do you turn a DiagramView into a Bitmap?
May 31st, 2024 at 12:50am
Print Post  
I tried to turn the DiagramView into a bitmap using DiagramView's DrawToBitmap() or Diagram.CreateImage(), but in both cases the image was displayed blank and the Nodes in the DiagramView could not be displayed.
Is the only way to make this possible to recursively turn each Node in the DiagramView into a bitmap?
I would appreciate it if you could teach me if there is a good way to do this.

Specifically, I would like to structure the Panel as shown below and convert each Panel into a Bitmap.

UserControl
 └Panel
    └DiagramView
    └Button
  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Offline


tech.support

Posts: 3228
Joined: Oct 19th, 2005
Re: How do you turn a DiagramView into a Bitmap?
Reply #1 - May 31st, 2024 at 5:56am
Print Post  
If you are using ControlNodes that host user controls, you will have to handle the DiagramView.PaintControl event to draw a representation of each control to the exported bitmap's Graphics -

https://www.mindfusion.eu/onlinehelp/flowchartnet/E_MindFusion_Diagramming_WinFo...

Regards,
Slavcho
Mindfusion
  
Back to top
 
IP Logged
 
koichi_satoh
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 25
Joined: Nov 30th, 2023
Re: How do you turn a DiagramView into a Bitmap?
Reply #2 - May 31st, 2024 at 7:18am
Print Post  
What triggers DiagramView.PaintControl to be hooked?
I was unable to hook DiagramView.PaintControl even when I called DrawToBitmap() or Diagram.CreateImage() on a Panel or UserControl.
  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Offline


tech.support

Posts: 3228
Joined: Oct 19th, 2005
Re: How do you turn a DiagramView into a Bitmap?
Reply #3 - May 31st, 2024 at 7:48am
Print Post  
That was assuming you are still using ControlNodes with DiagramViews inside as discussed in older threads. PaintControl should fire for the topmost DiagramView that's placed on the form, and not for the child DiagramViews.

Regards,
Slavcho
Mindfusion
« Last Edit: May 31st, 2024 at 12:11pm by Slavcho »  
Back to top
 
IP Logged
 
koichi_satoh
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 25
Joined: Nov 30th, 2023
Re: How do you turn a DiagramView into a Bitmap?
Reply #4 - Jun 3rd, 2024 at 1:27am
Print Post  
Thank you for your reply.
I'm thinking of changing ControlNodes to CompositeNodes.
In this case, can I hook it with DiagramView.PaintControl?
  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Offline


tech.support

Posts: 3228
Joined: Oct 19th, 2005
Re: How do you turn a DiagramView into a Bitmap?
Reply #5 - Jun 3rd, 2024 at 6:40am
Print Post  
Quote:
can I hook it with DiagramView.PaintControl


If you mean that in order to display nested diagrams inside your nodes, you could try calling the Diagram.Draw method in order to render a diagram as part of node's rendering. Or call Diagram.CreateImage and display the resulting bitmap.

These won't make the nested diagram interactive - if you need to also edit embedded diagrams, you could open a temporary DiagramView as an in-place editor in response to UI events.

Alternatively, you could try moving whatever you are currently displaying in nested diagrams to ContainerNodes.

So consider some variations of:

- create a custom component class, e.g. NestedDiagramComponent, and call diagram.Draw from ComponentBase.Draw override. Alternatively, show exported diagram image using ImageComponent. Then you could add the component to a CompositeNode along with other UI components.

- create a custom node class that overrides DrawLocal, or set CustomDraw property on ShapeNode and handle DrawNode event. Call diagram.Draw to render nested diagram inside the host node. Alternatively, show exported diagram image by setting ShapeNode.Image. You could use grouping to attach a CompositeNode with smaller UI elements to the host node.

- display current nested diagram contents in ContainerNodes instead. Attach composite node to container for extra UI.

Regards,
Slavcho
Mindfusion
  
Back to top
 
IP Logged
 
koichi_satoh
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 25
Joined: Nov 30th, 2023
Re: How do you turn a DiagramView into a Bitmap?
Reply #6 - Jun 3rd, 2024 at 6:55am
Print Post  
Thank you for your reply.
I'll try it!
  
Back to top
 
IP Logged
 
koichi_satoh
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 25
Joined: Nov 30th, 2023
Re: How do you turn a DiagramView into a Bitmap?
Reply #7 - Jun 12th, 2024 at 8:17am
Print Post  
By specifying the size of the UserControl  as an argument as shown below, the DiagramView was successfully converted to a Bitmap.

Code (CSS)
Select All
 public Bitmap CreateBitmap(Rectangle rectangle)
        {
            Bitmap bmpParent = new(rectangle.Width, rectangle.Height);
            using Graphics g = Graphics.FromImage(bmpParent);
            g.SmoothingMode = SmoothingMode.HighQuality;
            Bitmap bitmap = Diagram.CreateImage();
            bitmap.MakeTransparent(); // 背景透過
            Rectangle imageRectangle = DocToClient(Bounds);
            g.DrawImageUnscaled(bitmap, new Point(imageRectangle.Location.X, imageRectangle.Location.Y));
            return bmpParent;
        } 



However, the following two new problems have arisen.

1. Depending on the drawing position and size of the parent UserControl, the position of the Bitmap can shift by about 1px. This seems to be due to the coordinate conversion using DocToClient. Is it possible to absorb the error in the coordinate conversion with DocToClient?

2. If there is a text box being edited in the DiagramView, the text box being edited is not drawn on the Bitmap even when CreateBitmap is used. Is there a way to create a Bitmap that includes the text box being edited?
  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Offline


tech.support

Posts: 3228
Joined: Oct 19th, 2005
Re: How do you turn a DiagramView into a Bitmap?
Reply #8 - Jun 13th, 2024 at 8:05am
Print Post  
1. This build adds DocToClientF -> RectangleF method that does not truncate to integer values:

https://mindfusion.eu/_beta/fcnet703.zip

DrawImageUnscaled only accepts integer coordinates though, so you'd have to replace it with DrawImage(RectangleF) or DrawImage(float x, y, w, h) calls.

2. If you mean a TextBox inside your user control, you could draw its text from PaintControl event. If you mean the in-place text editor shown when items are double-clicked, you could get a reference to it by handling EnterInplaceEditMode event, and draw its text on the bitmap.

Regards,
Slavcho
Mindfusion
  
Back to top
 
IP Logged
 
koichi_satoh
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 25
Joined: Nov 30th, 2023
Re: How do you turn a DiagramView into a Bitmap?
Reply #9 - Jun 18th, 2024 at 1:34am
Print Post  
I tried DocToClientF, which I received as a solution to problem 1, but it did not solve the problem.
In the attached sample project, a table control is placed inside a DiagramView, and it is converted to a bitmap when focus is out. When converted to a bitmap, it is shifted by 1px to the bottom right. If you change the size or position of the table control, the direction of the shift when it is converted to a bitmap will change.
This behavior did not change even if I placed a DiagramView inside it instead of a table control and used DocToClientF.

Is there a problem with my implementation?
The bitmap conversion is done using the UpdateBitmap() method in GridNode.cs.
  

sample.zip ( 135 KB | 15 Downloads )
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Offline


tech.support

Posts: 3228
Joined: Oct 19th, 2005
Re: How do you turn a DiagramView into a Bitmap?
Reply #10 - Jun 18th, 2024 at 1:22pm
Print Post  
Attached code still calls DocToClient -

Code
Select All
private void UpdateBitmap()
{
    Rectangle rectangle = _view.DocToClient(Bounds);
    ...
 



Note that you must change the rectangle var declaration to RectangleF, or the conversion operator would still round coordinates to integer. Make sure later drawing code is using RectangleF too - currently there's a "new Rectangle " created for DrawToBitmap argument.

Also note that hosted controls are a bit smaller than Bounds due to ControlPadding property. If you are trying to align controls to their on-screen representation in diagram, you will have to deflate the rectangle by same value.
  
Back to top
 
IP Logged
 
koichi_satoh
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 25
Joined: Nov 30th, 2023
Re: How do you turn a DiagramView into a Bitmap?
Reply #11 - Jun 20th, 2024 at 12:05am
Print Post  
Thank you for your reply.

For 2, I was able to turn it into a bitmap by getting a reference to the text in the EnterInplaceEditMode event. However, only the text was drawn, the text box frame could not be drawn.

For 1, I was unable to solve the problem even when using RectangleF.
DrawToBitmap does not allow floats to be specified. Can this be solved by rounding when converting to int? Or is there another way?
Since 0 is specified for ControlPadding, it did not seem necessary to consider it.
  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Offline


tech.support

Posts: 3228
Joined: Oct 19th, 2005
Re: How do you turn a DiagramView into a Bitmap?
Reply #12 - Jun 20th, 2024 at 7:05am
Print Post  
If you are trying to align bitmap to on-screen representation of the control, then we are looking at it the wrong way Wink Windows Forms itself places controls only at integer coordinates, and even if ControlNode.Bounds in diagram's MeasureUnit would convert to non-integer ones in screen pixels, final location would still be rounded to int.

So you can get that position in pixels relative to the DiagramView using the Location property of WinForms.Control, or its Left/Top properties. Same for width and height in pixels: get values of Control's Bounds/Size/Width/Height properties.

Regards,
Slavcho
Mindfusion
  
Back to top
 
IP Logged
 
koichi_satoh
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 25
Joined: Nov 30th, 2023
Re: How do you turn a DiagramView into a Bitmap?
Reply #13 - Jun 25th, 2024 at 9:00am
Print Post  
When converting to Bitmap, you say that the Location property or its Left/Top properties of WinForms.Control are used, but does this refer to the Control specified as the EditControl of the CompositeNode?
The Control specified as EditControl does not retain information about coordinates, so I was unable to use the Location property or Left/Top property.
Is it possible to retain display coordinates with the Control specified as EditControl without using DocToClient?

Also, although I haven't tried it yet, if you adjust the coordinates and size so that they are not rounded by DocToClient when the CompositeNode is moved or resized, there may be no misalignment when it is converted to Bitmap.
  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Offline


tech.support

Posts: 3228
Joined: Oct 19th, 2005
Re: How do you turn a DiagramView into a Bitmap?
Reply #14 - Jun 25th, 2024 at 2:58pm
Print Post  
I was referring to the control hosted inside ControlNode; floating point coordinates of node.Bounds will always end up as integer pixels anyway when placing the hosted control as child of DiagramView, and you should be able to get them using properties of the WinForms.Control class.

Regarding the in-place edit TextBox control, you should be able to get its coordinates by handling EnterInplaceEditMode event. DiagramView raises it after the text box is positioned:

Code
Select All
inplaceTextBox.Bounds = ...;
Controls.Add(inplaceTextBox);
inplaceTextBox.Focus();
OnEnterInplaceEditMode(...); 



Regards,
Slavcho
Mindfusion
« Last Edit: Jun 26th, 2024 at 5:57am by Slavcho »  
Back to top
 
IP Logged
 
Page Index Toggle Pages: [1] 2 
Send TopicPrint