ListViewなどのItemsSourceにコレクションを設定して一覧を表示するには、個々のデータのクラスではフィールドではなくプロパティを公開していないとダメなようです。
そこを注意すれば他は定型でほぼ行けます。
注意点としては、SampleViewModelで保持するViewModelプロパティのコレクションはList<T>ではなく、ObservableCollection<T>がよいようです。(List<T>と同じように使えます)
最後にもう一つ、PropertyChangedイベントでデータの変更があったことを認識するようなので、コレクションの変更が変数のアドレスの比較だと、Addメソッドでの追加だとそのイベントは起きないのかなぁと思うので、
ローカル変数を作成してそっちに追加をして、最後に置き換えることで強制的にイベントを起こすようにするのがベターな気がします。
SampleClass.cs
namespace ItemsSourceSample { //要はプロパティを公開すればよい。 //フィールドはダメのようです。 public class SampleClass1 { public string className { get; set; } = "SampleClass1"; public string propName { get; set; } = "none"; public int count { get; set; } = 0; public SampleClass2 cls2 { get; set; } = new SampleClass2(0); public SampleClass1(int v) { this.count = v; } } public class SampleClass2 { public string className { get; set; } = "SampleClass2"; public int value { get; set; } = -1; public SampleClass2(int v) { this.value = v; } } }
BindableBase.cs
using System.ComponentModel; using System.Runtime.CompilerServices; namespace ItemsSourceSample { public class BindableBase : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected bool SetProperty<t>(ref T field, T value, [CallerMemberName]string propertyName = null) { if (Equals(field, value)) { return false; } field = value; var h = PropertyChanged; if (h != null) { h(this, new PropertyChangedEventArgs(propertyName)); } return true; } } }
SampleViewModel.cs
namespace ItemsSourceSample { public class SampleViewModel : BindableBase { private ObservableCollection<sampleclass1> _list = new ObservableCollection<sampleclass1>(); public ObservableCollection<sampleclass1> List { get { return this._list; } set { this.SetProperty(ref this._list, value); } } } }
MainPage.xamlの一部
<page.datacontext> <local:sampleviewmodel /> </page.datacontext> <grid background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <listview itemssource="{Binding Path=List}" margin="10,100,10,10" background="#FF266780"> <listview.itemtemplate> <datatemplate> <grid> <grid.columndefinitions> <columndefinition width="100" /> <columndefinition width="100" /> <columndefinition width="100" /> <columndefinition width="100" /> <columndefinition width="100" /> </grid.columndefinitions> <textblock text="{Binding Path=className}" grid.column="0" margin="5,0,5,0" /> <textblock text="{Binding Path=count}" grid.column="1" margin="5,0,5,0" /> <textblock text="{Binding Path=propName}" grid.column="2" margin="5,0,5,0" /> <textblock text="{Binding Path=cls2.className}" grid.column="3" margin="5,0,5,0" /> <textblock text="{Binding Path=cls2.value}" grid.column="4" margin="5,0,5,0" /> </grid> </datatemplate> </listview.itemtemplate> </listview> </grid>
MainPage.xaml.cs
namespace ItemsSourceSample { public sealed partial class MainPage : Page { public SampleViewModel ViewModel { get;set; } public MainPage() { this.InitializeComponent(); this.DataContextChanged += (s, e) => { this.ViewModel = this.DataContext as SampleViewModel; }; } private void Page_Loaded(object sender, RoutedEventArgs e) { //ローカルの変数を用意 ObservableCollection<sampleclass1> local = new ObservableCollection<sampleclass1>(); //ダミーデータをローカル変数に登録 local.Add(new SampleClass1(1)); local.Add(new SampleClass1(2)); local.Add(new SampleClass1(3)); local.Add(new SampleClass1(4)); local.Add(new SampleClass1(5)); local.Add(new SampleClass1(6)); local.Add(new SampleClass1(7)); local.Add(new SampleClass1(8)); //ローカル変数を代入することで、PropertyChangedイベントを発生させています。 this.ViewModel.List = local; } } }