WPF ListView にバインドの問題があります。ビュー モデルは INotifyPropertyChanged を実装して、データの更新時にトリガーされます。ただし、INotifyPropertyChanged を実装しない型 ("Person") の監視可能なコレクションが含まれています。
ListView は、起動後にバインドされた人物を表示します。これで問題ありません。しかし、モデルのデータ (人の年齢) を変更した後、視覚表現/バインディングを手動で更新する必要があります。これが私の問題です。
誰かが私を正しい方向に向けることができれば幸いです、ありがとう!
モデルは非常に単純です。
// does not implement INotifyPropertyChanged interface
class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
PersonList は、ItemsSource を介して ListView にバインドされる ObservableCollection です。
<ListView x:Name="ListViewPersons" ItemsSource="{Binding PersonList}">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"></GridViewColumn>
<GridViewColumn Header="Age" DisplayMemberBinding="{Binding Age}"></GridViewColumn>
</GridView>
</ListView.View>
</ListView>
ビューの分離コードは、「年齢の増加」をビューモデルに委任します。モデルのデータを変更した後、何らかの方法で GUI を更新する必要があります。ここに問題があります。
private void Button_Click(object sender, RoutedEventArgs e)
{
...
// increasing the age of each person in the model
viewModel.LetThemGetOlder();
**// how to update the View?**
// does not work
ListViewPersons.GetBindingExpression(ListView.ItemsSourceProperty)
.UpdateTarget();
// does not work either
ListViewPersons.InvalidateProperty(ListView.ItemsSourceProperty);
}
}
完全にするには、ViewModel:
class ViewModel : INotifyPropertyChanged
{
public ViewModel()
{
PersonList = new ObservableCollection<Person>
{
new Person {Name = "Ellison", Age = 56},
new Person {Name = "Simpson", Age = 44},
new Person {Name = "Gates", Age = 12},
};
}
internal void LetThemGetOlder()
{
foreach (var p in PersonList)
{
p.Age += 35;
}
}
private ObservableCollection<Person> _personList;
public ObservableCollection<Person> PersonList
{
get { return _personList; }
set
{
_personList = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}