2009-05-15 24 views
4

Ich habe eine ViewModel-Klasse, die eine Liste von Punkten enthält, und ich versuche, es an eine Polylinie zu binden. Die Polylinie nimmt die anfängliche Punktliste auf, merkt aber nicht, wenn zusätzliche Punkte hinzugefügt werden, obwohl ich INotifyPropertyChanged implementiere. Was ist los mit dir?Warum funktioniert diese Datenbindung nicht?

<StackPanel> 
    <Button Click="Button_Click">Add!</Button> 
    <Polyline x:Name="_line" Points="{Binding Pts}" Stroke="Black" StrokeThickness="5"/> 
</StackPanel> 

C# Seite:

// code-behind 
_line.DataContext = new ViewModel(); 
private void Button_Click(object sender, RoutedEventArgs e) 
{ 
    // The problem is here: NOTHING HAPPENS ON-SCREEN! 
    ((ViewModel)_line.DataContext).AddPoint(); 
} 

// ViewModel class 
public class ViewModel : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    public PointCollection Pts { get; set; } 

    public ViewModel() 
    { 
     Pts = new PointCollection(); 
     Pts.Add(new Point(1, 1)); 
     Pts.Add(new Point(11, 11)); 
    } 

    public void AddPoint() 
    { 
     Pts.Add(new Point(25, 13)); 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs("Pts")); 
    } 
} 
+0

Antwort aktualisiert, die Ursache gefunden. – Carlo

Antwort

1

Ihre PointCollections Änderungseigenschaft auf einer Abhängigkeitseigenschaft:

public PointCollection Pts 
     { 
      get { return (PointCollection)GetValue(PtsProperty); } 
      set { SetValue(PtsProperty, value); } 
     } 

     // Using a DependencyProperty as the backing store for Pts. This enables animation, styling, binding, etc... 
     public static readonly DependencyProperty PtsProperty = 
      DependencyProperty.Register("Pts", typeof(PointCollection), typeof(ViewModel), new UIPropertyMetadata(new PointCollection())); 

diese BTW tun, werden Sie nicht das Property Ereignis auslösen müssen.

Oh sorry, und das Objekt muss von DependencyObject

public class ViewModel : DependencyObject 
{ 
//... 
} 
+0

Es wird normalerweise nicht empfohlen, ViewModels als DependencyObjects zu implementieren, die viel schwerer als POCO sind und INotifyPropertyChanged implementieren ... trotzdem wird es in diesem Fall nichts ändern –

+0

Danke, hast du deine Antwort getestet? Die Verwendung von INotifyPropertyChanged funktioniert für mich, wenn ich es für andere Eigenschaften verwende, nur nicht für die Punktsammlung. – Qwertie

+0

Yeah testete es, ich änderte den Code beim Erstellen eines Punktes anstelle von Pts.Add (neuer Punkt (25, 13)); Ich habe Pts.Add (neuer Punkt (random.Next (0,100), random.Next (0,100))); und alle neuen zufälligen Punkte wurden erstellt und auf dem Bildschirm angezeigt. – Carlo

4

Es ist sehr wahrscheinlich, dass, da es in die Sammlung ist bindend, es so etwas wie ObservableCollection<T> benötigen. Was passiert, wenn Sie von PointCollection zu ObservableCollection<Point> wechseln?

+0

Ich habe gerade das gleiche Szenario getestet, die Bindung selbst funktioniert (die Points-Eigenschaft enthält die neuen Punkte) ... aber aus irgendeinem Grund wird die PolyLine nicht aktualisiert –

+0

Sehr interessant, Thomas. – Qwertie

+0

ObservableCollection funktioniert nicht. Selbst die Anfangszeile erscheint nicht auf dem Bildschirm; Offensichtlich unterstützt Polyline keine Bindung an ObservableCollection und unterstützt auch nicht die Liste . – Qwertie

1

i erben habe es durch die Implementierung INotifyCollectionChanged statt INotifyPropertyChanged als POCO zu arbeiten.

Verwandte Themen