У меня есть класс, который записывает начальную и конечную точки линии. Элементы этого класса добавляются в Observable Collection, которая служит источником ItemsSource моего ItemsControl.
Вот соответствующая часть XAML:
<ItemsControl Name="PathControl">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Line
Name="Path"
Stroke="Red"
StrokeThickness="4"
X1="{Binding
StartCoordinates.X,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"
Y1="{Binding
StartCoordinates.Y,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"
X2="{Binding
EndCoordinates.X,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"
Y2="{Binding
endCoordinates.Y,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
И вот соответствующий класс:
public class VisualPath: INotifyPropertyChanged
{
public VisualPath(Point start, Point end)
{
this.startCoordinates = start;
this.endCoordinates = end;
}
Point startCoordinates;
public Point StartCoordinates
{
get
{
return startCoordinates;
}
set
{
startCoordinates = value;
OnPropertyChanged();
}
}
Point endCoordinates;
public Point EndCoordinates
{
get
{
return endCoordinates;
}
set
{
endCoordinates = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Это соответствующая часть моего MainWindow:
public MainWindow()
{
InitializeComponent();
PathControl.ItemsSource = PathElements = new ObservableCollection<VisualPath>();
}
Я хотел бы создать несколько пар кнопок и соединить их линиями. Для этого я записываю абсолютное положение двух кнопок относительно сетки с событием клика. Я сохраняю положение первой кнопки в переменной Position (tempPoint), и когда я нажимаю на вторую кнопку (цель), в коллекцию должна быть добавлена новая строка (что происходит) с позицией 1-й кнопки как его X1 и Y1 (начальная точка) от tempPoint и положение второй кнопки как ее X2 и Y2 (конечная точка).
Вот методы, обрабатывающие события кликов:
private void firstButton_Click(object sender, RoutedEventArgs e)
{
Button pathInitiator = sender as Button;
if (pathInitiator != null)
{
tempPoint = pathInitiator.TranslatePoint(new Point(0, 0), MainGrid);
}
else
{
MessageBox.Show("Not Button");
}
}
private void secondButton_Click(object sender, RoutedEventArgs e)
{
Button pathTerminator = sender as Button;
if (pathTerminator != null)
{
GeneralTransform end = pathTerminator.TransformToVisual(this);
Point endPoint = end.Transform(new Point(0, 0));
PathElements.Add(new VisualPath(tempPoint, endPoint));
//PathElements.Add(new VisualPath(new Point(0, 0), new Point(200, 200)));
}
}
Хотя положение первого экземпляра первой кнопки обычно фиксируется правильно, конечная точка линии всегда находится не на своем месте, как и любые другие экземпляры первой кнопки. Отображаемые строки всегда кажутся перевернутыми или сдвинутыми, даже когда я пытался добавить несколько строк друг над другом (как показано закомментированными строками), новые строки всегда появляются под предыдущей. Моя проводка плохая или я чего-то не понимаю в том, как работают линии в WPF?
EDIT: Благодаря комментариям, теперь первый экземпляр пары работает так, как должен:
Mode=TwoWay
(и, следовательно, такжеUpdateSourceTrigger=PropertyChanged
) не имеет смысла для привязок X1, Y1, X2 и Y2. Кроме того, вместо Line вам, вероятно, лучше использовать Path с LineGeometry, где вы можете напрямую связать свойстваStartPoint
иEndPoint
. - person Clemens   schedule 08.02.2017