我正在 C#中开发 WPF ,我想多次绘制一条特定的行,而不会丢失以前的路径。我的buttons
内有 10 Grid
,而我按了一次,我想画一条线。对于该行,我使用var redLine
,每次按下按钮,它都会收到一对特定的坐标。
我使用此代码绘制线条:
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);
}
}
但是每次按button1
然后按button2
我都会收到此错误(其他按钮也会出现错误):
错误指定的Visual已经是另一个Visual的子项或者是其根 CompositionTarget。
我确实想要保留两行而不是删除第一行以便绘制第二行。关于如何解决它的任何想法?
注意我不想在每个buttonX_Click方法中声明每一行(整个程序中大约有11行)。
答案 0 :(得分:1)
错误消息非常清楚,Line
已经是MainGrid
的子元素。你不能再次添加它。
在将其添加到MainGrid之前,您必须创建一个新的Line
:
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);
}
显然,您也不再需要private Line redLine
成员了。
答案 1 :(得分:0)
我建议遵循此示例的方法(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 class ViewModelLine
{
public ViewModelLine()
{
_models = new ObservableCollection<ModelLine>();
}
ObservableCollection<ModelLine> _models;
public ObservableCollection<ModelLine> Models { get { return _models; } set { _models = value; } }
}
<强>模型强>
public class ModelLine : INotifyPropertyChanged
{
int _x1;
public int X1 { get { return _x1; } set { _x1 = value; RaisePropertyChanged("X1"); } }
int _x2;
public int X2 { get { return _x2; } set { _x2 = value; RaisePropertyChanged("X2"); } }
int _y1;
public int Y1 { get { return _y1; } set { _y1 = value; RaisePropertyChanged("Y1"); } }
int _y2;
public int Y2 { get { return _y2; } set { _y2 = value; RaisePropertyChanged("Y2"); } }
public event PropertyChangedEventHandler PropertyChanged;
void RaisePropertyChanged(string propname)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propname));
}
}
请注意,ModelLine
可以包含其他属性,例如“笔触”和“厚度”。