多次绘制相同的线,而不会丢失先前的路径

时间:2017-02-16 15:49:07

标签: c# wpf visual-studio lines children

我正在 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行)。

2 个答案:

答案 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可以包含其他属性,例如“笔触”和“厚度”。