トップ回答者
WPF リストボックスのバインディングソースが更新されたら常に最終行を表示する

質問
-
お世話になります。
表題の件、下記WEBの記事を参考に実装を行いました(環境はVBです)
http://kenzauros.com/blog/follow-last-item-of-wpf-listbox/
ですがソフト起動時にオブジェクトがからのため実行できないとのエラーメッセージが
表示されます。VBへのソースのコンバート内容がだめなのかと、C#でも試しましたが
同様の結果でした。
お詳しい方お見えでしたらご教授願えませんでしょうか?
回答
-
まず、webに出回っているWPFのコードのほとんどは、MVVMパターンで作成していることを前提にしていることをご承知ください。
さて、listBox2のItemsSourceは、{Binding Items, 以下略}と定義されています。これは、「DataContextに設定されているオブジェクトの、Itemsという名前のプロパティをソースとして扱う」という意味になります。
しかし、800ZOUさんはDataContextにObservableCollection<T>オブジェクトそのものを設定されています。ObservableCollection<T>はItemsプロパティを持っていないので、当然ながらItemsSourceはnullとなっていまいます。
単純には、ItemsSource="{Binding Mode=以下略}"のように、パスを指定しないことで「DataContextに設定されているオブジェクトそのものをソースとして扱う」ことを意味させるなどといった解決策が考え付きます。
あるいは、バインディングを使用しないコーディングスタイルで進めているのなら、{Binding}を使用せず、直接ItemsSourceプロパティにObservableCollection<T>を代入してしまってもいいでしょう。
もっとも、冒頭で述べた通り、WPFのサンプルはおおよそMVVMパターンを前提に記述されていますので、まずはMVVMパターンを学んだほうが良いようには思います。
- 回答の候補に設定 立花楓Microsoft employee, Moderator 2017年10月10日 5:09
- 回答としてマーク 立花楓Microsoft employee, Moderator 2017年10月19日 4:16
すべての返信
-
技術的にどう解決して良いかというよりは、思った通りに動いてない、つまりデバッグの問題であるように思います。
オブジェクトが空というのではあれば、原因はそこなので、空になっている原因を調査してみて下さい。
最終行にスクロールする機能を実装する前に、ちゃんと表示されますか?もし、それでもわからない場合は、試されている最低限のコードをここに提示されると良いと思います。言葉で説明するよりもコードの方が的確に伝わることも多いです。
★良い回答には回答済みマークを付けよう! MVP - .NET http://d.hatena.ne.jp/trapemiya/
- 編集済み trapemiyaModerator 2017年10月10日 0:24
- 回答の候補に設定 立花楓Microsoft employee, Moderator 2017年10月10日 5:26
-
お世話になります。
Viewmodel側のコードは下記となります。
<ListBox x:Name="listBox2" Grid.Row="4" ItemsSource="{Binding Items, Mode=OneWay, UpdateSourceTrigger =PropertyChanged, NotifyOnTargetUpdated=True}" TargetUpdated="ListBox_TargetUpdated"/>
Web上の記事とほとんと変わらないかと思います。
ソースコード記載部は下記となります。
①リストボックスの更新用のバインディングデータを下記で定義↓
ObservableCollection<string> list = new ObservableCollection<string>();
②UIとのバインディング?を実施
listBox2.DataContext = this.list;
③イベントの登録。ソフト起動時に下記関数が実行され「オブジェクト参照がオブジェクトインスタンスに、、」とのエラーが
発生します。listBox2.ItemsSourceの中身を見るとNULLになっております。
private void ListBox_TargetUpdated(object sender, DataTransferEventArgs e)
{
(listBox2.ItemsSource as INotifyCollectionChanged).CollectionChanged += new NotifyCollectionChangedEventHandler(listBox_CollectionChanged);
}
void listBox_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
this.listBox2.ScrollIntoView(this.listBox2.Items[this.listBox2.Items.Count - 1]);
} -
お世話になります。
Viewmodel側のコードは下記となります。
表示もされていないので初期化時にエラーになっていることはわかります。
<ListBox x:Name="listBox2" Grid.Row="4" ItemsSource="{Binding Items, Mode=OneWay, UpdateSourceTrigger =PropertyChanged, NotifyOnTargetUpdated=True}" TargetUpdated="ListBox_TargetUpdated"/>
Web上の記事とほとんと変わらないかと思います。
ListBox_TargetUpdatedがソフトの起動時呼ばれるようですが、その際にListBox2.Itemsourceの中身がNULLに
なっているためにエラーが起きているようです。
ソースコード記載部は下記となります。
①リストボックスの更新用のバインディングデータを下記で定義↓
ObservableCollection<string> list = new ObservableCollection<string>();
②UIとのバインディング?を実施
listBox2.DataContext = this.list;
③イベントの登録。ソフト起動時に下記関数が実行され「オブジェクト参照がオブジェクトインスタンスに、、」とのエラーが
発生します。listBox2.ItemsSourceの中身を見るとNULLになっております。
private void ListBox_TargetUpdated(object sender, DataTransferEventArgs e)
{
(listBox2.ItemsSource as INotifyCollectionChanged).CollectionChanged += new NotifyCollectionChangedEventHandler(listBox_CollectionChanged);
}
void listBox_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
this.listBox2.ScrollIntoView(this.listBox2.Items[this.listBox2.Items.Count - 1]);
} -
まず、webに出回っているWPFのコードのほとんどは、MVVMパターンで作成していることを前提にしていることをご承知ください。
さて、listBox2のItemsSourceは、{Binding Items, 以下略}と定義されています。これは、「DataContextに設定されているオブジェクトの、Itemsという名前のプロパティをソースとして扱う」という意味になります。
しかし、800ZOUさんはDataContextにObservableCollection<T>オブジェクトそのものを設定されています。ObservableCollection<T>はItemsプロパティを持っていないので、当然ながらItemsSourceはnullとなっていまいます。
単純には、ItemsSource="{Binding Mode=以下略}"のように、パスを指定しないことで「DataContextに設定されているオブジェクトそのものをソースとして扱う」ことを意味させるなどといった解決策が考え付きます。
あるいは、バインディングを使用しないコーディングスタイルで進めているのなら、{Binding}を使用せず、直接ItemsSourceプロパティにObservableCollection<T>を代入してしまってもいいでしょう。
もっとも、冒頭で述べた通り、WPFのサンプルはおおよそMVVMパターンを前提に記述されていますので、まずはMVVMパターンを学んだほうが良いようには思います。
- 回答の候補に設定 立花楓Microsoft employee, Moderator 2017年10月10日 5:09
- 回答としてマーク 立花楓Microsoft employee, Moderator 2017年10月19日 4:16
-
詳しいご説明を記載頂き誠にありがとうございました。
解決することができましたのでお礼を申し上げます。
MVVMをこれから少しづつ勉強していこうと思います。
- 編集済み 立花楓Microsoft employee, Moderator 2017年10月12日 5:33 回答者が異なるため