C# 多次绘制同一条线,而不丢失以前的轨迹
我正在C#中开发一个WPF,我想多次绘制一条特定的线,而不会丢失它以前的轨迹。我的C# 多次绘制同一条线,而不丢失以前的轨迹,c#,wpf,visual-studio,lines,children,C#,Wpf,Visual Studio,Lines,Children,我正在C#中开发一个WPF,我想多次绘制一条特定的线,而不会丢失它以前的轨迹。我的网格中有10个按钮,当我按下一个按钮时,我想画一条线。对于该行,我使用var红线,每次按下按钮,它都会收到一对特定的坐标 我用这个代码来画一条线: public partial class MainWindow : Window { private Line redLine = new Line(); SolidColorBrush redBrush = new SolidColorBrush(C
网格中有10个按钮
,当我按下一个按钮时,我想画一条线。对于该行,我使用var红线
,每次按下按钮,它都会收到一对特定的坐标
我用这个代码来画一条线:
public partial class MainWindow : Window {
private Line redLine = new Line();
SolidColorBrush redBrush = new SolidColorBrush(Colors.Red);
public MainWindow()
{
redLine.StrokeThickness = 4;
redLine.Stroke = redBrush;
}
private void button1_Click(object sender, RoutedEventArgs e) {
redLine.X1 = 237;
redLine.Y1 = 382;
redLine.X2 = 288;
redLine.Y2 = 409;
//draw the line
MainGrid.Children.Add(redLine);
}
private void button2_Click(object sender, RoutedEventArgs e) {
redLine.X1 = 130;
redLine.Y1 = 323;
redLine.X2 = 238;
redLine.Y2 = 690;
//draw the line
MainGrid.Children.Add(redLine);
}
}
但每次我按按钮1
然后再按按钮2
时,我都会出现此错误(其他按钮也会出现此错误):
错误指定的视觉对象已经是另一个视觉对象的子对象或其根对象
合成目标
我想保留这两条线,而不是为了画第二条而删除第一条线。有没有办法解决这个问题
注意我不想在每个按钮单击方法中声明每一行(整个程序中大约有11行)。错误消息非常清楚,行
已经是MainGrid
的子元素。你不能再添加一次
在将其添加到主网格之前,您必须创建一个新的行
:
private void button1_Click(object sender, RoutedEventArgs e)
{
var newLine = new Line
{
Stroke = redBrush,
StrokeThickness = 4,
X1 = 237,
Y1 = 382,
X2 = 288,
Y2 = 409
};
MainGrid.Children.Add(newLine);
}
显然,您也不再需要私有行redLine
成员了。我建议遵循这个示例的方法(MVVM)。它通过单击按钮随机添加新行
主窗口
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModelLine();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
ViewModelLine vm = (ViewModelLine)DataContext;
// use other information and decide how you want to add the line
Random ran = new Random();
vm.Models.Add(new ModelLine() { X1=ran.Next(1,600), X2= ran.Next(1, 600), Y1= ran.Next(1, 600), Y2= ran.Next(1, 600) });
}
}
<DockPanel >
<Button Content="Add a New Line" DockPanel.Dock="Top" Click="Button_Click"/>
<ItemsControl DockPanel.Dock="Bottom" DataContext="{Binding}" ItemsSource="{Binding Models}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Line X1="{Binding X1}" X2="{Binding X2}" Y1="{Binding Y1}" Y2="{Binding Y2}"
Stroke="Black" StrokeThickness="2"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</DockPanel>
查看
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModelLine();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
ViewModelLine vm = (ViewModelLine)DataContext;
// use other information and decide how you want to add the line
Random ran = new Random();
vm.Models.Add(new ModelLine() { X1=ran.Next(1,600), X2= ran.Next(1, 600), Y1= ran.Next(1, 600), Y2= ran.Next(1, 600) });
}
}
<DockPanel >
<Button Content="Add a New Line" DockPanel.Dock="Top" Click="Button_Click"/>
<ItemsControl DockPanel.Dock="Bottom" DataContext="{Binding}" ItemsSource="{Binding Models}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Line X1="{Binding X1}" X2="{Binding X2}" Y1="{Binding Y1}" Y2="{Binding Y2}"
Stroke="Black" StrokeThickness="2"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</DockPanel>
请注意,ModelLine
可以包含笔划和厚度等其他属性。“我不想在每个按钮单击方法中声明每一行(整个程序中大约有11行)。”为什么不呢?这可能会解决问题。是否纯粹是为了不必重复宽度/画笔等的实例化/设置?是否应该使用CheckBox
es来显示/隐藏线条?在WPF中,您可以使用数据模板来可视化项目集合(在您的案例行中)。看见只需将新项目添加到集合中,就可以在视图中显示新行。@JamesThorpe从编程角度来看,反复声明每一行并不“正确”。我没有说这是最终解决方案,我只是想知道这是否是不重新声明它的原因。如果这是原因,还有其他方法,比如让每个按钮调用一个只提供坐标的函数,让这个函数创建直线,设置属性并添加它。@Sinatr我正在尝试创建类似于“图像地图”的东西。所以我不想要复选框,因为它将始终显示,不像按钮。我知道它是MainGrid的子元素。但是我希望避免每次都创建一条新线(正如我提到的,在10个按钮中有11条线被多次使用。难道我不能做任何其他事情吗?你不能向任何父控件添加两次一条线元素。但是,还有其他方法可以“绘制”WPF中的内容。从这里开始阅读:。感谢您的努力和时间。我将在每个单独的按钮单击方法中声明每一行