2017-02-16 26 views
-2

我开发一个WPFC#,我想多次,画中的特定行,而不会丢失之前的小径。我有 buttons里面我的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已经是另一个视觉的子元素或 CompositionTarget的根。

我确实想保留两条线,而不是删除第一条,以便绘制第二条。任何想法如何解决它?

注意我不想在每个buttonX_Click方法中声明每行(在整个程序中大约有11行)。

+0

_“我不想在每个buttonX_Click方法中声明每一行(整个程序中大约有11行)。”_为什么不呢?这可能会解决问题。是纯粹的,所以你不必重复宽度/画笔等的实例化/设置? –

+1

它不应该是'CheckBox'es显示/隐藏线?在WPF中,您可以使用数据模板来可视化项目集合(在您的案例行中)。请参阅[this](http://stackoverflow.com/a/23564452/1997232)。只需将新项目添加到集合中,即可在视图中显示新行。 – Sinatr

+0

@JamesThorpe从编程角度来看,我没有发现它是“正确的”,一次又一次地声明每一行。 –

回答

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成员了。

+0

我知道它是MainGrid的子元素。但是我希望避免每次都创建一个新行(正如我所提到的那样,在10个按钮中有很多次使用了11行)是不是我可以做的其他事情? –

+0

您不能将任何一行元素添加到任何行父控制。然而,还有其他方法可以在WPF中“绘制”东西。从这里开始阅读:[WPF概述中的形状和基本绘图](https://msdn.microsoft.com/zh-cn/library/ms747393(v = vs.110).aspx) – Clemens

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可以包含其它属性,如中风和厚度。

+0

感谢您的努力和时间,我将在每个单独的buttonX_click方法中声明每一行 –

相关问题