WPF:动态创建的行没有出现在定义的位置
WPF: Dynamically created line does not appear at defined position
我有一个class记录一条线的起点和终点。此 class 的元素被添加到 Observable 集合中,作为我的 ItemsControl 的 ItemsSource。
这里是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>
这里是对应的class:
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));
}
}
这是我的主窗口的相关部分:
public MainWindow()
{
InitializeComponent();
PathControl.ItemsSource = PathElements = new ObservableCollection<VisualPath>();
}
我想创建多对按钮并用线连接它们。为此,我通过单击事件记录了两个按钮相对于网格的 absolute 位置。我将第一个按钮的位置存储在位置变量 (tempPoint) 中,当我单击第二个按钮(目标)时,应该将新行添加到集合(发生)中,第一个按钮的位置为它的 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 中的线路是如何工作的?
编辑:
感谢评论,现在这对的第一个实例按应有的方式工作:
但是这对的任何其他实例都放错了地方:
如果您希望线条彼此重叠,您可以将 ItemsControl
的 ItemsPanelTemplate
设置为 Grid
:
<ItemsControl Name="PathControl">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<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}" />
<TextBlock Text="{Binding EndCoordinates.Y}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
我有一个class记录一条线的起点和终点。此 class 的元素被添加到 Observable 集合中,作为我的 ItemsControl 的 ItemsSource。
这里是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>
这里是对应的class:
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));
}
}
这是我的主窗口的相关部分:
public MainWindow()
{
InitializeComponent();
PathControl.ItemsSource = PathElements = new ObservableCollection<VisualPath>();
}
我想创建多对按钮并用线连接它们。为此,我通过单击事件记录了两个按钮相对于网格的 absolute 位置。我将第一个按钮的位置存储在位置变量 (tempPoint) 中,当我单击第二个按钮(目标)时,应该将新行添加到集合(发生)中,第一个按钮的位置为它的 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 中的线路是如何工作的?
编辑: 感谢评论,现在这对的第一个实例按应有的方式工作:
但是这对的任何其他实例都放错了地方:
如果您希望线条彼此重叠,您可以将 ItemsControl
的 ItemsPanelTemplate
设置为 Grid
:
<ItemsControl Name="PathControl">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<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}" />
<TextBlock Text="{Binding EndCoordinates.Y}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>