2010-11-18 10 views
0

Dies ist meine einfache Xaml, die in einem Textfeld das Alter der ersten Person in einer Sammlung von Personen zeigt. Ich verstehe nicht, dass ich nach dem Klick das Alter nicht ändere.Wpf - Problem mit der Bindung an eine Sammlung Artikel

<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="132*" /> 
     <RowDefinition Height="179*" /> 
    </Grid.RowDefinitions> 
    <TextBlock Text="{Binding Persons[0].Age}" /> 
    <Button Grid.Row="1" Click="Button_Click">Change Age</Button> 
</Grid> 

Dies ist der Code hinter der XAML:

public partial class MainWindow : Window 
{ 
    public ObservableCollection<Person> Persons { get; set; } 

    public MainWindow() { 
     Persons = new ObservableCollection<Person>(); 
     Persons.Add(new Person{Age = -1}); 

     DataContext = this; 
     InitializeComponent(); 
    } 

    private void Button_Click(object sender, RoutedEventArgs e) { 
     (Persons[0] as Person).Age = 5; 
    } 
} 

das ist Klasse Person:

public class Person : INotifyPropertyChanged 
{ 
    private int _age; 

    public int Age 
    { 
     get { return _age; } 
     set 
     { 
      _age = value; 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs("Age")); 
      } 
     } 
    } 

    #region INotifyPropertyChanged Members 

    public event PropertyChangedEventHandler PropertyChanged; 

    #endregion 
} 
+0

Ihr Code funktionierte gut für mich, als ich es gerade in ein WPF-Projekt in Visual Studio 2010 eingefügt habe. Welche Version von WPF und Visual Studio verwenden Sie? –

+0

Arbeitete ganz gut für mich. Kopieren/Einfügen zum Projekt und es funktioniert wie ein Zauber. Wenn Sie einen Haltepunkt für "Age" festlegen, wird PropertyChanged oder null ausgelöst? –

Antwort

1

, die wahrscheinlich ist, weil die Ansicht fangen nicht, dass eine Eigenschaft eines Elements der Liste geändert. Es fängt nur, dass die Liste geändert (Elemente hinzufügen oder entfernen)

private void Button_Click(object sender, RoutedEventArgs e) { 

    (Persons[0] as Person).Age = 5; 
    Person p = Persons.First(); 
    Persons.Remove(0); 
    Persons.Add(p); 
} 
+0

Dies sollte jedoch nicht notwendig sein, da die Person-Klasse selbst INotifyPropertyChange implementiert. (Tatsächlich funktioniert der ursprüngliche Code auf meinem System einwandfrei.) Hier passiert nur, dass sich die Age-Eigenschaft eines einzelnen Personenobjekts ändert - Benachrichtigungen auf Listenebene sind nicht einmal notwendig. Tatsächlich, wenn ich ObservableCollection durch List ersetze, funktioniert es weiter - die Eigenschaftsänderungsbenachrichtigungen, die Person anhebt, funktionieren korrekt. –

+0

Das Objekt Person sendet wahrscheinlich den INotifyPropertyChange. Sie sind jedoch nicht an die Person gebunden. Sie sind an das erste Element einer ObservableCollection gebunden, sodass nur Adds oder Removes aus der Sammlung abgefangen werden. – dcarneiro

+0

Sie könnten etwas tun, bei dem jede "Person" ein PropertyChange-Ereignis erhält, das die Änderung des Ereignisses "Persons" auslöst – Rachel

0

Ihr Code korrekt ist, haben Sie INotifyPropertyChanged auf Ihrer Klasse implementiert, so dass alle gut sein sollte.

Sind Sie sicher, dass es sich nicht ändert?

+0

Ja, ich bin mir sicher .. – Erez

0

Ich habe versucht Ihren Code und es hat perfekt für mich gearbeitet. Ich habe sogar den Button-Click-Handler geändert, sodass ich weiterklicken und das TextBlock-Update sehen konnte.

private void Button_Click(object sender, RoutedEventArgs e) 
{ 
    (Persons[0] as Person).Age = (Persons[0] as Person).Age + 1; 
}