How can I cut a Line drawn on canvas into two parts - c#

Say I drew a Line on a Canvas. I need simply cut/split the Line to have two lines.
Line line = new Line();
SolidColorBrush brush = new SolidColorBrush();
brush.Color = colorPicker2.SelectedColor;
line.Stroke = brush;
line.StrokeThickness = SliderThickness.Value;
line.X1 = currentPoint.X;
line.Y1 = currentPoint.Y;
line.X2 = e.GetPosition(DrawPanel).X;
line.Y2 = e.GetPosition(DrawPanel).Y;
currentPoint = e.GetPosition(DrawPanel);
DrawPanel.Children.Add(line);
I'm sorry that I wasn't been specific. The user will click on a point of the line and the line will be cut at that point into two pieces. Then the user will drag or move each part of the line.

Try this:
var middleX = (line.X1 + line.X2) / 2;
var middleY = (line.Y1 + line.Y2) / 2;
Line line1 = new Line();
line1.X1 = line.X1;
line1.Y1 = line.Y1;
line1.X2 = middleX;
line1.Y2 = middleY;
Line line2 = new Line();
line2.X1 = middleX;
line2.Y1 = middleY;
line2.X2 = line.X2;
line2.Y2 = line.Y2;

Try this:
Line line = new Line();
SolidColorBrush brush = new SolidColorBrush();
brush.Color = colorPicker2.SelectedColor;
line.Stroke = brush;
line.StrokeThickness = SliderThickness.Value;
line.X1 = currentPoint.X;
line.Y1 = currentPoint.Y;
line.X2 = e.GetPosition(DrawPanel).X;
line.Y2 = e.GetPosition(DrawPanel).Y;
currentPoint = e.GetPosition(DrawPanel);
DrawPanel.Children.Add(line);
Point middlePoint = ((line.X1 + line.X2) / 2, (line.Y1 + line.Y2) / 2)
Line newFirst = new Line();
newFirst.X1 = line.X1;
newFirst.Y1 = line.Y1;
newFirst.X2 = middlePoint.X;
newFirst.Y2 = middlePoint.Y;
newFirst.Stroke = brush;
newFirst.StrokeThickness = SliderThickness.Value;
Line newSecond = new Line();
newSecond.X1 = middlePoint.X;
newSecond.Y1 = middlePoint.Y;
newSecond.X2 = line.X2;
newSecond.Y2 = line.Y2;
newSecond.Stroke = brush;
newSecond.StrokeThickness = SliderThickness.Value;
DrawPanel.Children.Remove(line);
DrawPanel.Children.Add(newFirst);
DrawPanel.Children.Add(newSecond);

Related

Viewing applications in WPF with errors

I have an application that breaks the image when the screen size changes
Below is the screen
Where can the mistake be? What can cause this situation? I do not even know where to look because it is not a permanent error only once and once is gone
This is how I load items with a line and number per view:
<ItemsControl ItemsSource="{Binding ConnectorsGridsHorizontal, Mode=TwoWay}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
Function drawing 1 element:
public Grid DrawConnector1(Thickness margin, int nr, bool rotate, bool rightSide)
{
Grid grid = new Grid();
grid.Margin = margin;
grid.HorizontalAlignment = HorizontalAlignment.Left;
grid.Width = S10;
grid.Height = 128;
grid.VerticalAlignment = System.Windows.VerticalAlignment.Center;
Line line = new Line();
line.X1 = S10HALF;
line.X2 = S10HALF;
line.Y1 = 0;
line.Y2 = 128;
line.StrokeDashArray = new System.Windows.Media.DoubleCollection() { 4, 2, 1, 2 };
line.Stroke = System.Windows.Media.Brushes.Green;
line.StrokeThickness = 4;
grid.Children.Add(line);
Grid inGrid = new Grid();
inGrid.Width = S10;
inGrid.Height = HF;
inGrid.Background = System.Windows.Media.Brushes.Black;
grid.Children.Add(inGrid);
Border br = new Border();
br.BorderThickness = new Thickness(0);
br.CornerRadius = new CornerRadius(10);
br.Background = System.Windows.Media.Brushes.White;
br.Margin = new Thickness(-10, -10, -10, -10);
br.Width = 20;
br.Height = 20;
br.VerticalAlignment = rightSide ? VerticalAlignment.Top : VerticalAlignment.Bottom;
br.RenderSize = new System.Windows.Size(br.ActualWidth + 1, br.ActualHeight + 1);
if (SelectedConnector + 1 == nr) br.Background = System.Windows.Media.Brushes.Green;
else br.Background = System.Windows.Media.Brushes.White;
if (DisableGreenMark) br.Background = System.Windows.Media.Brushes.White;
TextBlock txtBlock = new TextBlock();
txtBlock.FontSize = 16;
txtBlock.Text = nr.ToString();
txtBlock.Foreground = new SolidColorBrush(Colors.Black);
txtBlock.VerticalAlignment = VerticalAlignment.Center;
txtBlock.HorizontalAlignment = HorizontalAlignment.Center;
br.Child = txtBlock;
grid.Children.Add(br);
Binding b = new Binding("S60_20");
b.Mode = BindingMode.Default;
grid.SetBinding(Canvas.TopProperty, b);
return grid;
}
GIF:
I'm also using SnapsToDevicePixels="true"
To start with, try doing this:
br.HorizontalAlignment = HorizontalAlignment.Stretch;
br.Margin = new Thickness(0, 0, 0, 0);
Do not use margin with a negative value
Stretch will provide you with an element extension
Side cut is probably caused by too narrow a strip for the element:
You have:
grid.Width = S10;
line.X1 = S10HALF;
line.X2 = S10HALF;
This indicates that you have the width set to probably 10
and Here you have set to 20
br.Width = 20;
br.Height = 20;
I also suggest changing here:
grid.Width = S10 * 2;
line.X1 = S10HALF * 2;
line.X2 = S10HALF * 2;

UWP animation is not proper when duration is set below 1 sec

I am animating a rectangle and a pair of lines
in uwp, such that the rectangle animates from its center and the lines animate from the top of the rectangle to its position. When I set duration less than 1 sec animation is not proper .
But with the same duration(such as 0.8, 0.7) it is working fine in wpf. This occurs on initial loading, when on dynamically animating it works.
Storyboard sb;
Rectangle rect;
Line highLine;
Line lowLine;
double width, height, x_center, y_center;
private void DrawElement()
{
rect = new Rectangle();
rect.RenderTransformOrigin = new Point(0.5, 0.5);
rect.Height = 60;
rect.Width = 40;
rect.Stroke = new SolidColorBrush(Colors.Black);
rect.StrokeThickness = 2;
rect.RenderTransform = new ScaleTransform();
grid.Children.Add(rect);
width = grid.ActualWidth;
height = grid.ActualHeight;
x_center = width / 2;
y_center = height / 2;
highLine = new Line();
highLine.RenderTransform = new ScaleTransform();
highLine.StrokeThickness = 2;
highLine.X1 = highLine.X2 = x_center;
highLine.Y1 = y_center - rect.Height/2 - 30;
highLine.Y2 = y_center - rect.Height/2;
highLine.Stroke = new SolidColorBrush(Colors.Red);
grid.Children.Add(highLine);
lowLine = new Line();
lowLine.RenderTransform = new ScaleTransform();
lowLine.StrokeThickness = 2;
lowLine.X1 = lowLine.X2 = x_center;
lowLine.Y1 = y_center + rect.Height / 2 + 30;
lowLine.Y2 = y_center + rect.Height / 2;
lowLine.Stroke = new SolidColorBrush(Colors.Green);
grid.Children.Add(lowLine);
AnimationLogics();
}
private void AnimationLogics()
{
string rectPath = "(UIElement.RenderTransform).(ScaleTransform.ScaleY)";
string y1_path = "Y1";
string y2_Path = "Y2";
sb = new Storyboard();
//rect animation
DoubleAnimation da = new DoubleAnimation();
da.From = 0;
da.To = 1;
da.Duration = TimeSpan.FromSeconds(2);
#if !WPF
da.EnableDependentAnimation = true;
Storyboard.SetTargetProperty(da, rectPath);
#else
Storyboard.SetTargetProperty(da, new PropertyPath(rectPath));
#endif
Storyboard.SetTarget(da, rect);
sb.Children.Add(da);
// high line animation
DoubleAnimation da1 = new DoubleAnimation();
da1.From = y_center;
da1.To = highLine.Y1;
da1.Duration = TimeSpan.FromSeconds(2);
#if !WPF
da1.EnableDependentAnimation = true;
Storyboard.SetTargetProperty(da1, y1_path);
#else
Storyboard.SetTargetProperty(da1, new PropertyPath(y1_path));
#endif
Storyboard.SetTarget(da1, highLine);
sb.Children.Add(da1);
DoubleAnimation da2 = new DoubleAnimation();
da2.From = y_center;
da2.To = highLine.Y2;
da2.Duration = TimeSpan.FromSeconds(2);
#if !WPF
da2.EnableDependentAnimation = true;
Storyboard.SetTargetProperty(da2, y2_Path);
#else
Storyboard.SetTargetProperty(da2, new PropertyPath(y2_Path));
#endif
Storyboard.SetTarget(da2, highLine);
sb.Children.Add(da2);
//low line animation
DoubleAnimation da3 = new DoubleAnimation();
da3.From = y_center;
da3.To = lowLine.Y1;
da3.Duration = TimeSpan.FromSeconds(2);
#if !WPF
da3.EnableDependentAnimation = true;
Storyboard.SetTargetProperty(da3, y1_path);
#else
Storyboard.SetTargetProperty(da3, new PropertyPath(y1_path));
#endif
Storyboard.SetTarget(da3, lowLine);
sb.Children.Add(da3);
DoubleAnimation da4 = new DoubleAnimation();
da4.From = y_center;
da4.To = lowLine.Y2;
da4.Duration = TimeSpan.FromSeconds(2);
#if !WPF
da4.EnableDependentAnimation = true;
Storyboard.SetTargetProperty(da4, y2_Path);
#else
Storyboard.SetTargetProperty(da4, new PropertyPath(y2_Path));
#endif
Storyboard.SetTarget(da4, lowLine);
sb.Children.Add(da4);
sb.Begin();
}
private void grid_SizeChanged(object sender, SizeChangedEventArgs e)
{
grid.Children.Clear();
DrawElement();
}

Moving a group of elements on Canvas

I want to draw a signal image as shown below at runtime on canvas.
sample code which I used to draw this signal is as below.
Ellipse Ellipse1 = new Ellipse();
Ellipse Ellipse2 = new Ellipse();
Ellipse Ellipse3 = new Ellipse();
Line lineV = new Line();
Line lineH = new Line();
lineV.Stroke = SystemColors.WindowFrameBrush;
lineV.X1 = EndPosition.X;
lineV.Y1 = EndPosition.Y;
lineV.X2 = StartPosition.X;
lineV.Y2 = EndPosition.Y;
SolidColorBrush redBrush = new SolidColorBrush();
redBrush.Color = Colors.Black;
lineV.StrokeThickness = 2;
lineV.Stroke = redBrush;
canvas1.Children.Add(lineV);
lineH.Stroke = SystemColors.WindowFrameBrush;
lineH.X1 = StartPosition.X;
lineH.Y1 = EndPosition.Y;
lineH.X2 = StartPosition.X;
lineH.Y2 = StartPosition.Y;
redBrush.Color = Colors.Black;
lineH.StrokeThickness = 2;
lineH.Stroke = redBrush;
canvas1.Children.Add(lineH);
SolidColorBrush mySolidColorBrush1 = new SolidColorBrush();
mySolidColorBrush1.Color = Colors.Red; //FromArgb(255, 255, 255, 0);
Ellipse1.Fill = mySolidColorBrush1;
Ellipse1.StrokeThickness = 2;
Ellipse1.Stroke = Brushes.Black;
Ellipse1.Width = 30;
Ellipse1.Height = 30;
Ellipse1.Margin = new Thickness(EndPosition.X, EndPosition.Y - 15, EndPosition.X + 50, EndPosition.Y + 50);
canvas1.Children.Add(Ellipse1);
SolidColorBrush mySolidColorBrush2 = new SolidColorBrush();
mySolidColorBrush2.Color = Colors.Green; //FromArgb(255, 255, 255, 0);
Ellipse2.Fill = mySolidColorBrush2;
Ellipse2.StrokeThickness = 2;
Ellipse2.Stroke = Brushes.Black;
Ellipse2.Width = 30;
Ellipse2.Height = 30;
Ellipse2.Margin = new Thickness(EndPosition.X + 30, EndPosition.Y - 15, EndPosition.X + 60, EndPosition.Y + 50);
canvas1.Children.Add(Ellipse2);
SolidColorBrush mySolidColorBrush3 = new SolidColorBrush();
mySolidColorBrush3.Color = Colors.Yellow; // FromArgb(255, 255, 255, 0);
Ellipse3.Fill = mySolidColorBrush3;
Ellipse3.StrokeThickness = 2;
Ellipse3.Stroke = Brushes.Black;
Ellipse3.Width = 30;
Ellipse3.Height = 30;
Ellipse3.Margin = new Thickness(EndPosition.X + 60, EndPosition.Y - 15, EndPosition.X + 150, EndPosition.Y + 50);
canvas1.Children.Add(Ellipse3);
**Now I want the user to be able to interactively move this signal on the canvas on mouse move events.
How can I able to do this ?**
Iam using C# WPF.
If want to implement a canvas to drag elements, a DragCanvas is your choice.
Dragging Elements in a Canvas from Josh Smith and after Dragging Elements in a Canvas from igkutikov that adapt Josh Smith code. There are articles with #mustread category.
With the dragCanvas you can implement a full functionality Dragging Element Canvas, and better adapt to your code. Happy coding!

Lines Shapes and Shananagins

So, Basically I'm trying to draw a line between the center of 2 ellipses
And I think this should do it:
Path myPath = new Path();
myPath.Stroke = System.Windows.Media.Brushes.Black;
myPath.StrokeThickness = 4;
myPath.HorizontalAlignment = HorizontalAlignment.Left;
myPath.VerticalAlignment = VerticalAlignment.Center;
EllipseGeometry myEllipseGeometry = new EllipseGeometry();
myEllipseGeometry.Center = new System.Windows.Point((xQuard * 10) + 100, yQuard * 10);
myEllipseGeometry.RadiusX = 2;
myEllipseGeometry.RadiusY = 2;
myPath.Data = myEllipseGeometry;
GraphPanel.Children.Add(myPath);
//if it's not the first point...
if (prevA != 0.0)
{
Path iLine = new Path();
iLine.Stroke = Brushes.Black;
iLine.StrokeThickness = 4;
iLine.HorizontalAlignment = HorizontalAlignment.Left;
myPath.VerticalAlignment = VerticalAlignment.Center;
LineGeometry iLineGeometry = new LineGeometry();
iLineGeometry.StartPoint = myEllipseGeometry.Center;
iLineGeometry.EndPoint = new System.Windows.Point(prevA, prevB);
iLine.Data = iLineGeometry;
GraphPanel.Children.Add(iLine);
}
//Set the previous point(s)
prevA = (xQuard * 10) + 100;
prevB = yQuard * 10;
Now as you can see, I've set the Line's StartPoint = to the first ellipse start point
And Yet....
Why is the Line's start point in the picture not the center of the point on the left?
I think you mean iLine.VerticalAlignment instead of myPath.VerticalAlignment the second time, right?

Connect two UIElement with Arc

I have two UIElements(i.e. rectangles) in Canvas and their coordinates. How can I connect them with arc in code behind?
No need to get an exact hit on the rectangles (or other objects): make sure the Z ordering is correct. arc.SetValue(Canvas.ZIndex, -1) will push it to the background. If you want a perpendicular hit, you'll need to break out the algebra :/
For the arc: (see http://msdn.microsoft.com/en-us/library/ms751808.aspx), it needs to be contained in a PathFigure.
Edit: this shows two connected rectangles. The line simple runs between the two centers. The arc starts on one center (the pathFigure startpoint), first argument is the center of the second object.
r1 = new Rectangle();
r1.Margin = new Thickness(50, 50, 0, 0);
r1.VerticalAlignment = System.Windows.VerticalAlignment.Top;
r1.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
r1.Height = 50;
r1.Width= 50;
r1.Fill = new SolidColorBrush(Colors.Red);
r2 = new Rectangle();
r2.Width = 50;
r2.Height = 50;
r2.Fill = new SolidColorBrush(Colors.Blue);
r2.Margin = new Thickness(350, 450, 0, 0);
r2.VerticalAlignment = System.Windows.VerticalAlignment.Top;
r2.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
l = new Line();
l.X1 = 75;
l.Y1 = 75;
l.X2 = 375;
l.Y2 = 475;
l.Fill = new SolidColorBrush(Colors.Purple);
l.Stroke = new SolidColorBrush(Colors.Purple);
l.StrokeThickness = 2;
l.SetValue(Canvas.ZIndexProperty, -1);
PathGeometry myPathGeometry = new PathGeometry();
// Create a figure.
PathFigure pathFigure1 = new PathFigure();
pathFigure1.StartPoint = new Point(75, 75);
pathFigure1.Segments.Add(
new ArcSegment(
new Point(375, 475),
new Size(50, 50),
45,
true, /* IsLargeArc */
SweepDirection.Clockwise,
true /* IsStroked */ ));
myPathGeometry.Figures.Add(pathFigure1);
// Display the PathGeometry.
Path myPath = new Path();
myPath.Stroke = Brushes.Black;
myPath.StrokeThickness = 1;
myPath.Data = myPathGeometry;
myPath.SetValue(Canvas.ZIndexProperty, -1);
LayoutRoot.Children.Add(r1);
LayoutRoot.Children.Add(r2);
LayoutRoot.Children.Add(l);
LayoutRoot.Children.Add(myPath);

Categories