2つの座標をつなぐ(縄のような)PNG画像があれば、
coordinateA.x;
coordinateA.y;
coordinateB.x;
coordinateB.y;
2 つの座標は常に変化し続けるため、2 つの座標間を接続する PNG 画像はサイズ変更と回転が必要です。
これを簡単にするサンプルコードはありますか?
2つの座標をつなぐ(縄のような)PNG画像があれば、
coordinateA.x;
coordinateA.y;
coordinateB.x;
coordinateB.y;
2 つの座標は常に変化し続けるため、2 つの座標間を接続する PNG 画像はサイズ変更と回転が必要です。
これを簡単にするサンプルコードはありますか?
これが私のアプローチです:
座標.cs:
public class Coordinates : DependencyObject
{
public Coordinates(double x, double y)
{
X = x;
Y = y;
}
public Coordinates()
{
X = 0;
Y = 0;
}
//X Dependency Property
public double X
{
get { return (double)GetValue(XProperty); }
set { SetValue(XProperty, value); }
}
public static readonly DependencyProperty XProperty =
DependencyProperty.Register("X", typeof(double), typeof(Coordinates), new UIPropertyMetadata(0d));
//Y Dependency Property
public double Y
{
get { return (double)GetValue(YProperty); }
set { SetValue(YProperty, value); }
}
public static readonly DependencyProperty YProperty =
DependencyProperty.Register("Y", typeof(double), typeof(Coordinates), new UIPropertyMetadata(0d));
}
Geometry.cs:
public class ConnectorLocationConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var start = (Coordinates)values[0];
var end = (Coordinates)values[1];
return new Thickness(start.X, start.Y, 0, 0);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
return null;
}
}
public class ConnectorAngleConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var start = (Coordinates)values[0];
var end = (Coordinates)values[1];
//dy/dx = tan(t) => t = arcTan(dy/dx)
double t = Math.Atan2(
Math.Abs(start.Y - end.Y),
Math.Abs(start.X - end.X)) * 180 / Math.PI;
if (end.X <= start.X && end.Y >= start.Y) return 180 - t;
if (end.X >= start.X && end.Y <= start.Y) return -t;
if (end.X <= start.X && end.Y <= start.Y) return 180 + t;
return t;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
return null;
}
}
public class ConnectorWidthConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var start = (Coordinates)values[0];
var end = (Coordinates)values[1];
//get side for states
return Math.Abs(start.X - end.X);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
return null;
}
}
public class ConnectorHeightConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var start = (Coordinates)values[0];
var end = (Coordinates)values[1];
//get side for states
return Math.Abs(start.Y - end.Y);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
return null;
}
}
MainWindow.xaml.cs:
//nothing fancy here
public MainWindow()
{
Start = new Coordinates();
End = new Coordinates();
DataContext = this;
InitializeComponent();
}
//Start Dependency Property
public Coordinates Start
{
get { return (Coordinates)GetValue(StartProperty); }
set { SetValue(StartProperty, value); }
}
public static readonly DependencyProperty StartProperty =
DependencyProperty.Register("Start", typeof(Coordinates), typeof(MainWindow), new UIPropertyMetadata(null));
//End Dependency Property
public Coordinates End
{
get { return (Coordinates)GetValue(EndProperty); }
set { SetValue(EndProperty, value); }
}
public static readonly DependencyProperty EndProperty =
DependencyProperty.Register("End", typeof(Coordinates), typeof(MainWindow), new UIPropertyMetadata(null));
//--------------------------------------------------
//Click causes the mouse position stick to Start/End
//--------------------------------------------------
bool flag = false;
private void Canvas_MouseMove(object sender, MouseEventArgs e)
{
var p = e.GetPosition(this);
if(flag) Start = new Coordinates(p.X, p.Y);
else End = new Coordinates(p.X, p.Y);
}
private void Canvas_MouseDown(object sender, MouseButtonEventArgs e)
{
flag = !flag;
}
そして最後に MainWindow.xaml:
<Window x:Class="WpfTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfTest"
Title="MainWindow" Height="650" Width="825">
<Window.Resources>
<local:ConnectorLocationConverter x:Key="connectorLocationConverter"/>
<local:ConnectorAngleConverter x:Key="connectorAngleConverter"/>
<local:ConnectorWidthConverter x:Key="connectorWidthConverter"/>
<local:ConnectorHeightConverter x:Key="connectorHeightConverter"/>
</Window.Resources>
<Canvas Background="#2000"
MouseMove="Canvas_MouseMove" MouseDown="Canvas_MouseDown">
<Canvas Width="0" Height="0">
<Image Source="/WpfTest;component/im.png" Stretch="Fill">
<Image.Margin>
<MultiBinding Converter="{StaticResource connectorLocationConverter}">
<Binding Path="Start"/>
<Binding Path="End"/>
</MultiBinding>
</Image.Margin>
<Image.Width>
<MultiBinding Converter="{StaticResource connectorWidthConverter}">
<Binding Path="Start"/>
<Binding Path="End"/>
</MultiBinding>
</Image.Width>
<Image.Height>
<MultiBinding Converter="{StaticResource connectorHeightConverter}">
<Binding Path="Start"/>
<Binding Path="End"/>
</MultiBinding>
</Image.Height>
<Image.RenderTransform>
<RotateTransform CenterX="0" CenterY="0">
<RotateTransform.Angle>
<MultiBinding Converter="{StaticResource connectorAngleConverter}">
<Binding Path="Start"/>
<Binding Path="End"/>
</MultiBinding>
</RotateTransform.Angle>
</RotateTransform>
</Image.RenderTransform>
</Image>
</Canvas>
</Canvas>
</Window>