2017-02-16 53 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方法中聲明每一行 –

相關問題