Closed zt199510 closed 4 months ago
Thank you for your assistance and for maintaining such a useful project.
Hi, thanks for the kind words. Here are two examples:
<UserControl x:Class="Nodify.Shapes.Canvas.CustomConnectionView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Nodify.Shapes.Canvas"
d:DataContext="{d:DesignInstance Type=local:ConnectionViewModel}"
mc:Ignorable="d">
<Canvas>
<Line X1="{Binding Source.Anchor.X}"
X2="{Binding Target.Anchor.X}"
Y1="{Binding Source.Anchor.Y}"
Y2="{Binding Target.Anchor.Y}"
Stroke="White"
StrokeThickness="3"
Cursor="Hand" />
<Border x:Name="CustomElement"
Visibility="Hidden">
<Ellipse Stretch="Fill"
Fill="#38754e"
Stroke="#5cc180"
StrokeThickness="2"
Width="50"
Height="50" />
</Border>
</Canvas>
</UserControl>
OnMouseEnter
and OnMouseLeave
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace Nodify.Shapes.Canvas
{
public partial class CustomConnectionView : UserControl
{
public CustomConnectionView2()
{
InitializeComponent();
}
protected override void OnMouseEnter(MouseEventArgs e)
{
var connection = (ConnectionViewModel)DataContext;
var midPoint = (Vector)((Vector)connection.Target.Anchor + connection.Source.Anchor) / 2;
var center = new Point(midPoint.X - CustomElement.ActualWidth / 2, midPoint.Y - CustomElement.ActualHeight / 2);
System.Windows.Controls.Canvas.SetTop(CustomElement, center.Y);
System.Windows.Controls.Canvas.SetLeft(CustomElement, center.X);
CustomElement.Visibility = Visibility.Visible;
}
protected override void OnMouseLeave(MouseEventArgs e)
{
CustomElement.Visibility = Visibility.Hidden;
}
}
}
ConnectionTemplate
of the NodifyEditor
to use the custom connection view<nodify:NodifyEditor ...>
<nodify:NodifyEditor.ConnectionTemplate>
<DataTemplate DataType="{x:Type local:ConnectionViewModel}">
<local:CustomConnectionView />
</DataTemplate>
</nodify:NodifyEditor.ConnectionTemplate>
</nodify:NodifyEditor>
In the previous example, you can notice that the math to get the midpoint is simple because we use a line for the connection. However, that's not the case for the built-in connection. We can use the GetTextPosition
method from the BaseConnection
to get the text position returning the midpoint for LineConnection
and Connection
(bezier curve), and the midpoint of the largest segment for StepConnection
and CircuitConnection
.
This is needed because the GetTextPosition
method is protected and we need it to calculate the midpoint.
using System.Globalization;
using System.Windows;
using System.Windows.Media;
namespace Nodify.Shapes.Canvas
{
public class StepConnectionAdapter : StepConnection
{
private static readonly FormattedText _dummyText = new FormattedText(string.Empty, CultureInfo.InvariantCulture, FlowDirection.LeftToRight, new Typeface("Times New Roman"), 1, Brushes.Red, 120);
public Point GetMidpoint()
{
(Vector sourceOffset, Vector targetOffset) = GetOffset();
return GetTextPosition(_dummyText, Source + sourceOffset, Target + targetOffset);
}
}
}
<UserControl x:Class="Nodify.Shapes.Canvas.StepConnectionView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Nodify.Shapes.Canvas"
d:DataContext="{d:DesignInstance Type=local:ConnectionViewModel}"
mc:Ignorable="d">
<Canvas>
<local:StepConnectionAdapter x:Name="StepConnectionRef"
Source="{Binding Source.Anchor}"
Target="{Binding Target.Anchor}"
SourcePosition="{Binding Source.Position}"
TargetPosition="{Binding Target.Position}"
Cursor="Hand"
Stroke="White"
StrokeThickness="3" />
<Border x:Name="CustomElement"
Visibility="Hidden">
<Ellipse Stretch="Fill"
Fill="#38754e"
Stroke="#5cc180"
StrokeThickness="2"
Width="50"
Height="50" />
</Border>
</Canvas>
</UserControl>
OnMouseEnter
and OnMouseLeave
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace Nodify.Shapes.Canvas
{
public partial class StepConnectionView : UserControl
{
public CustomConnectionView()
{
InitializeComponent();
}
protected override void OnMouseEnter(MouseEventArgs e)
{
var midPoint = StepConnectionRef.GetMidpoint();
var center = new Point(midPoint.X - CustomElement.ActualWidth / 2, midPoint.Y - CustomElement.ActualHeight / 2);
System.Windows.Controls.Canvas.SetTop(CustomElement, center.Y);
System.Windows.Controls.Canvas.SetLeft(CustomElement, center.X);
CustomElement.Visibility = Visibility.Visible;
}
protected override void OnMouseLeave(MouseEventArgs e)
{
CustomElement.Visibility = Visibility.Hidden;
}
}
}
ConnectionTemplate
of the NodifyEditor
to use the custom connection view<nodify:NodifyEditor ...>
<nodify:NodifyEditor.ConnectionTemplate>
<DataTemplate DataType="{x:Type local:ConnectionViewModel}">
<local:StepConnectionView />
</DataTemplate>
</nodify:NodifyEditor.ConnectionTemplate>
</nodify:NodifyEditor>
Let me know if you have any questions.
Thank you
I hope this message finds you well. I am currently working on a project where I am utilizing your library. I would like to know how I can make a custom element appear in the middle of a connection line when the mouse cursor hovers over it. Could you please provide an example or guide me on how to achieve this?