Page Index Toggle Pages: 1 Send TopicPrint
Hot Topic (More than 10 Replies) Control ShapeNode (Read 4856 times)
JackPan
Full Member
***
Offline


I Love MindFusion!

Posts: 134
Joined: Apr 9th, 2020
Control ShapeNode
Sep 15th, 2020 at 7:38am
Print Post  
Hi, Slavcho Smiley

private void CreateNodes(string path)
{
    var myImage = new BitmapImage(new Uri(path, UriKind.Relative));

    var imageWidthPx = myImage.PixelWidth * GetScreenDpi() / myImage.DpiX;
    var imageHeightPx = myImage.PixelHeight * GetScreenDpi() / myImage.DpiY;
    var imageWidth = GraphicsUnit.Pixel.Convert(imageWidthPx, diagram.MeasureUnit);
    var imageHeight = GraphicsUnit.Pixel.Convert(imageHeightPx, diagram.MeasureUnit);
    imageNode = diagram.Factory.CreateShapeNode(0, 0, imageWidth, imageHeight);
    imageNode.Image = myImage;
    imageNode.Shape = Shapes.Rectangle;
    imageNode.Locked = true;
    imageNode.ImageAlign = ImageAlign.BottomRight;
    double.TryParse(textBoxW.Text, out overlayNodeWidth);
    double.TryParse(textBoxH.Text, out overlayNodeHeight);
    var newBounds = new System.Windows.Rect(imageNode.Bounds.Right - overlayNodeWidth, imageNode.Bounds.Bottom - overlayNodeHeight, overlayNodeWidth, overlayNodeHeight);
    // Change the node's position / dimensions
    overlayNode.SetBounds(newBounds, true, true);

    overlayNode.EnabledHandles ^= AdjustmentHandles.Move | AdjustmentHandles.BottomHandles | AdjustmentHandles.RightHandles;

    zoomInMax = overlayNode.Bounds;

    diagram.InvalidateForeground();
}

The above piece of code realizes the creation of two ShapeNodes in the diagram instance, imageNode and overlayNode. There are a few problems I don’t understand very well:
1. imageNode.ImageAlign = ImageAlign.BottomRight; what this code does here What is it?

2. When the overlayNode is created, it is fixed at the lower right corner of the imageNode, which is achieved by these two lines of code: double.TryParse(textBoxW.Text, out overlayNodeWidth);
double.TryParse(textBoxH.Text, out overlayNodeHeight);var newBounds = new System.Windows.Rect(imageNode.Bounds.Right-overlayNodeWidth, imageNode.Bounds.Bottom-overlayNodeHeight, overlayNodeWidth, overlayNodeHeight);overlayNode.SetBounds(newBounds, true , true); However, I change the value in the TextBox:
private void tb_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
    Regex re = new Regex("[^0-9]+");

    e.Handled = re.IsMatch(e.Text);

}
That is, after changing the value of textBoxW or textBoxH, overlayNode is no longer fixed at the lower right corner of the imageNode, but at the upper left corner of the imageNode. Why is this happening? How can I modify the program to keep the overlayNode at the bottom right corner of the imageNode?

3. May I ask this code: overlayNode.EnabledHandles ^= AdjustmentHandles.Move | AdjustmentHandles.BottomHandles | AdjustmentHandles.RightHandles; and this code: zoomInMax = overlayNode.Bounds; What is the function?

4. How to change this regular expression to limit the value to only two decimal places?

Best regards.
  

9_15_0.png ( 86 KB | 112 Downloads )
9_15_0.png
Back to top
 
IP Logged
 
Lyubo
God Member
*****
Offline


MindFusion team

Posts: 511
Joined: Jun 17th, 2010
Re: Control ShapeNode
Reply #1 - Sep 15th, 2020 at 2:00pm
Print Post  
Hi,

1) The ImageAlign property is responsible for aligning the image inside a ShapeNode. In the case of BottomRight, it'll attempt to align the image to the bottom-right corner of the node.

2) The code you've provided is incomplete to determine what may be causing it. It may be parsing error or something else.

3) overlayNode.EnabledHandles ^= AdjustmentHandles.Move | AdjustmentHandles.BottomHandles | AdjustmentHandles.RightHandles; - It disables the Move, Bottom and Right adjustment handles;
zoomInMax = overlayNode.Bounds; - I can only guess it sets a limit to a zooming in function to the size of this overlayNode.

4) Answers in this thread seem to do the trick: https://stackoverflow.com/questions/308122/simple-regular-expression-for-a-decim...

Regards,
Lyubo
MindFusion
  
Back to top
 
IP Logged
 
JackPan
Full Member
***
Offline


I Love MindFusion!

Posts: 134
Joined: Apr 9th, 2020
Re: Control ShapeNode
Reply #2 - Sep 16th, 2020 at 1:39am
Print Post  
Hi, Lyubo Smiley

I haven't seen you for a while. I remember that the functions CreateNodes and tb_PreviewTextInput were taught by you. Thank you and Slavcho. Smiley

The program compiles and runs without errors. The function CreateNodes creates imageNode and overlayNode. The overlayNode is set at the bottom right of the imageNode, but if I change the width and height of the overlayNode, the result is that the overlayNode is at the top left of the imageNode. I want to understand why this is the case, and what modifications should be made to it so that the width and height of the overlayNode will not affect the position of the overlayNode in the imageNode. The result I want is that the overlayNode remains at the bottom right of the imageNode. I have debugged the program and found that changing the width and height of ovelayNode will enter the function tb_PreviewTextInput, and execute these two lines of code:
Regex re = new Regex("[^0-9]+");
e.Handled = re.IsMatch(e.Text);
will cause the location of overlayNode to change. Do I need to change these two lines of code or need to make other changes?

Best regards.
  

9_16_n0.png ( 266 KB | 107 Downloads )
9_16_n0.png
9_16_n1.png ( 275 KB | 111 Downloads )
9_16_n1.png
9_16_n2.png ( 193 KB | 119 Downloads )
9_16_n2.png
Back to top
 
IP Logged
 
Lyubo
God Member
*****
Offline


MindFusion team

Posts: 511
Joined: Jun 17th, 2010
Re: Control ShapeNode
Reply #3 - Sep 16th, 2020 at 5:30am
Print Post  
Hello Smiley

It's impossible for these two lines of code to be changing the bounds of the overlayNode. All those two lines of code do is using a regular expression to permit only numerical input to your text boxes.

I can only guess, that where you update the bounds of the node, you set the location of the overlayNode to the (0,0) Point, but as I said in my previous post, the code you provide is incomplete, so I can't really say with certainty why that happens.

To change the width and height of the overlayNode, while it remains anchored to the bottom-right corner, can use the following logic:
Code
Select All
			double width, height;
			// parse the input
			if (double.TryParse(textBoxW.Text, out width) && double.TryParse(textBoxH.Text, out height))
			{
				// limit the new width and height to the image node dimensions
				width = Math.Min(width, imageNode.Bounds.Width);
				height = Math.Min(height, imageNode.Bounds.Height);

				// calculate the difference between the old and new size
				var dx = width - overlayNode.Bounds.Width;
				var dy = height - overlayNode.Bounds.Height;

				// update the size
				var newBounds = new Rect(overlayNode.Bounds.X - dx, overlayNode.Bounds.Y - dy, width, height);
				overlayNode.SetBounds(newBounds, true, true);
				imageNode.InvalidateVisual();
			} 



Regards,
Lyubo
MindFusion
  
Back to top
 
IP Logged
 
JackPan
Full Member
***
Offline


I Love MindFusion!

Posts: 134
Joined: Apr 9th, 2020
Re: Control ShapeNode
Reply #4 - Sep 16th, 2020 at 8:01am
Print Post  
Hi, Lyubo Smiley

Because I want to overlap the lower right border of the overlayNode with the lower right border of the imageNode and make them unable to be dragged, I added the code overlayNode.EnabledHandles ^= AdjustmentHandles.Move | AdjustmentHandles.BottomHandles | AdjustmentHandles.RightHandles; But it failed. The result is that the lower right boundary of the overlayNode does not coincide with the lower right boundary of the imageNode. It just realizes that the overlayNode cannot be dragged in the right and down directions.
The following attachments are all the codes of the main window class of my current program. Please help me analyze the problem and how to solve this problem?

Best regards.
  

AOI.rar ( 10 KB | 122 Downloads )
9_16_5.png ( 1249 KB | 111 Downloads )
9_16_5.png
Back to top
 
IP Logged
 
Lyubo
God Member
*****
Offline


MindFusion team

Posts: 511
Joined: Jun 17th, 2010
Re: Control ShapeNode
Reply #5 - Sep 17th, 2020 at 6:30am
Print Post  
Hi,

In your code, there's a TextBox LostFocus handler, that sets the location of your overlayNode to 0,0. Makes sure to keep it bottom-right aligned there, using the same logic in your CreateNodes method, where you've actually commented out the aligning.

Regards,
Lyubo
MindFusion
  
Back to top
 
IP Logged
 
JackPan
Full Member
***
Offline


I Love MindFusion!

Posts: 134
Joined: Apr 9th, 2020
Re: Control ShapeNode
Reply #6 - Sep 17th, 2020 at 7:57am
Print Post  
Thanks very much, Lyubo. Smiley

I got it, corrected it, and the effect was finally realized.

I would like to ask what is the difference between the following two pieces of code:
1. double.TryParse(textBoxW.Text, out overlayNodeWidth);
            double.TryParse(textBoxH.Text, out overlayNodeHeight);
            var newBounds = new System.Windows.Rect(imageNode.Bounds.Right - overlayNodeWidth, imageNode.Bounds.Bottom - overlayNodeHeight, overlayNodeWidth, overlayNodeHeight);
            // Change the node's position / dimensions
            overlayNode.SetBounds(newBounds, true, true);

            overlayNode.EnabledHandles ^= AdjustmentHandles.Move | AdjustmentHandles.BottomHandles | AdjustmentHandles.RightHandles;

            diagram.InvalidateForeground();

2.   double width, height;
            // parse the input
            if (double.TryParse(textBoxW.Text,out width) && double.TryParse(textBoxH.Text, out height))
            {
                // limit the new width and height to the image node dimensions
                width = Math.Min(width, imageNode.Bounds.Width);
                height = Math.Min(height, imageNode.Bounds.Height);

                // calculate the difference between the old and new size
                var dx = width - overlayNode.Bounds.Width;
                var dy = height - overlayNode.Bounds.Height;

                // update the size
                var newBounds = new System.Windows.Rect(overlayNode.Bounds.X - dx, overlayNode.Bounds.Y - dy, width, height);
                overlayNode.EnabledHandles ^= AdjustmentHandles.Move | AdjustmentHandles.BottomHandles | AdjustmentHandles.RightHandles;
                zoomInMax = overlayNode.Bounds; // The bigger node in your example, replace/inflate if needed by your requirements
                overlayNode.SetBounds(newBounds, true, true);
                imageNode.InvalidateVisual();
            }

Best regards.
  
Back to top
 
IP Logged
 
JackPan
Full Member
***
Offline


I Love MindFusion!

Posts: 134
Joined: Apr 9th, 2020
Re: Control ShapeNode
Reply #7 - Sep 17th, 2020 at 8:36am
Print Post  
Hi, Lyubo. Smiley

I would like to ask the following question in this topic:

I tried to comment out the code imageNode.ImageAlign = ImageAlign.BottomRight; the result is the same as before: the overlayNode is still docked at the bottom right of the imageNode. I don't quite understand the function of this code. I want to know how to control the docking position of the overlayNode. Because I need to dock the overlayNode at the bottom left or bottom right of the imageNode for my choice. How should it be achieved?

I already know this code: overlayNode.EnabledHandles ^= AdjustmentHandles.Move | AdjustmentHandles.BottomHandles | AdjustmentHandles.RightHandles; The realization function is to prohibit the whole of the overlayNode from being dragged and to prohibit the right side of the overlayNode and its bottom from being dragged, if I need to change to prohibit dragging of the left and bottom edges of ovelayNode, just change this code to: overlayNode.EnabledHandles ^= AdjustmentHandles.Move | AdjustmentHandles.BottomHandles | AdjustmentHandles.LeftHandles;

Thank you for your explanation!

Best regards.
  

9_17_n0.png ( 283 KB | 109 Downloads )
9_17_n0.png
9_17_1.png ( 148 KB | 111 Downloads )
9_17_1.png
Back to top
 
IP Logged
 
Lyubo
God Member
*****
Offline


MindFusion team

Posts: 511
Joined: Jun 17th, 2010
Re: Control ShapeNode
Reply #8 - Sep 17th, 2020 at 9:12am
Print Post  
Hi,

JackPan wrote on Sep 17th, 2020 at 7:57am:
(...)
I would like to ask what is the difference between the following two pieces of code: (...)


The first example sets the initial position of the overlayNode by aligning it to the bottom-right of the imageNode. The second piece of code assumes the overlayNode is already aligned, and just repositions it after its size has been changed.

JackPan wrote on Sep 17th, 2020 at 8:36am:
I tried to comment out the code imageNode.ImageAlign = ImageAlign.BottomRight; the result is the same as before: the overlayNode is still docked at the bottom right of the imageNode. I don't quite understand the function of this code. I want to know how to control the docking position of the overlayNode. Because I need to dock the overlayNode at the bottom left or bottom right of the imageNode for my choice. How should it be achieved?


The ImageAlign property has nothing to do with your overlayNode. As I already explained above, it's responsible for postioning the image set to the ShapeNode.Image property.

To "dock" the overlayNode, you'd use the already provided code above when you change its size.

Regards,
Lyubo
MindFusion
  
Back to top
 
IP Logged
 
JackPan
Full Member
***
Offline


I Love MindFusion!

Posts: 134
Joined: Apr 9th, 2020
Re: Control ShapeNode
Reply #9 - Sep 21st, 2020 at 2:34am
Print Post  
Hi, Lyubo Smiley

1.I use the regular expression \d+(\.\d{1,2})? in the link to limit the text value of the TextBox to at least one digit before the decimal point and at most two digits after the decimal point. But the result was an error: Unrecognized escape sequence.
As shown in screenshot 9_21_5 and screenshot 9_21_6.
How should this code be modified?

2.I want to use the following regular expression to set the TextBox to only enter 0-360 as the angle value:
private void angle_PreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            Regex re = new Regex("^([1-9]|([1-9][0-9])|([1-2][0-9][0-9])|([3][0-5][0-9])|([0]{1}))$|^[3][6][0]$");

            e.Handled = re.IsMatch(e.Text);
        }
But the result was unexpected, and it turned out that only English letters can be input.
As shown in screenshot 9_21_9.
How should this code be modified?

Best regards.
« Last Edit: Sep 21st, 2020 at 4:00am by JackPan »  

9_21_5.png ( 22 KB | 110 Downloads )
9_21_5.png
9_21_6.png ( 12 KB | 111 Downloads )
9_21_6.png
9_21_9.png ( 1 KB | 112 Downloads )
9_21_9.png
Back to top
 
IP Logged
 
Lyubo
God Member
*****
Offline


MindFusion team

Posts: 511
Joined: Jun 17th, 2010
Re: Control ShapeNode
Reply #10 - Sep 21st, 2020 at 7:43am
Print Post  
Hi,

1) You need to use valid C# regex syntax, e.g. escape the backslashes - new Regex("\\d+(\\.\\d{1,2})?");

2) You're filtering all the valid values instead of invalid. Change your code to e.Handled = !regex.IsMatch(e.Text);

Regards,
Lyubo
MindFusion
  
Back to top
 
IP Logged
 
JackPan
Full Member
***
Offline


I Love MindFusion!

Posts: 134
Joined: Apr 9th, 2020
Re: Control ShapeNode
Reply #11 - Sep 21st, 2020 at 8:49am
Print Post  
Hi, Lyubo. Smiley

Please don't mind if I continue this question, I changed the code to
private void tb_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
Regex re = new Regex(" \\ d + (\\. \\ d {1,2})?");

e.Handled =! re.IsMatch(e.Text);

}
As a result, the decimal point cannot be entered. May I ask where I am wrong? I don't understand this code very well: e.Handled = !re.IsMatch(e.Text);
my understanding is that if the regular expression is matched successfully, the Preview event does not need to be bubbled. Is this understanding?

Best regards.
  
Back to top
 
IP Logged
 
Lyubo
God Member
*****
Offline


MindFusion team

Posts: 511
Joined: Jun 17th, 2010
Re: Control ShapeNode
Reply #12 - Sep 23rd, 2020 at 5:18am
Print Post  
Hi,

When you set Handled to false in this case, you're right in your assumption, that the event will stop propagating and thus the invalid input will be discarded.

It doesn't work as you expect, as this is actually the PreviewTextInput event, and e.Text in this case is just new input, not the whole content of the TextBox, i.e. when you input the decimal place, e.Text is ".", which your regular expression won't match.

You can use PreviewTextInput to check if the input is either a digit or a decimal place, then validate if the whole text is a valid number in a TextChanged event.

Regards,
Lyubo
MindFusion
  
Back to top
 
IP Logged
 
JackPan
Full Member
***
Offline


I Love MindFusion!

Posts: 134
Joined: Apr 9th, 2020
Re: Control ShapeNode
Reply #13 - Sep 23rd, 2020 at 6:17am
Print Post  
Thanks very much, Lyubo. Smiley

After your explanation, now I finally understand. It turns out that the TextInput event only responds to new input, so the regular matching should not be placed in the TextInput event, but it should be placed in the TextChanged event. In this case, make a mark in the TextInput event as a record of whether there is a decimal point input, and write a regular expression with or without a decimal point in the TextChanged event according to this mark.

Best regards.
  
Back to top
 
IP Logged
 
Page Index Toggle Pages: 1
Send TopicPrint