質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.51%

  • C#

    9062questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • WPF

    828questions

    Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

  • MVVM

    106questions

    MVVM(Model View ViewModel)は構築上のデザインパターンで、表現ロジック(ViewModel)によってデータ(Model)からページ(View)を分離させます。

TreeViewとListBoxを使って表示連携するときのベストな実装

受付中

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 118

siksmtt

score 11

前提・実現したいこと

WPF(MVVMパターン)を使ってツリー(TreeView)とリスト(ListBox)の表示連携をしたいと思っています。
例えば以下のような構成だとします。

<TreeView イメージ>
日本
 |
 ーー東日本
    |
    ーー東北
    --関東
 ーー西日本
<関東を選択時のListBox>
東京
神奈川
埼玉

<東日本を選択時のListBox>
青森
秋田
東京
神奈川

上記のように、ListBoxに47都道府県のリストを入れ、
各地域を選択したときにListBoxに表示される一覧を更新させるアプリケーションを作っています。

ロジックについて

現時点では47都道府県(47アイテム)を持つリストをバインディングし、
ツリービューの選択遷移のイベントにてListBoxItemのVisibilityCollapsedなどをsetしている動きになっています。

前提:47アイテムを持つ "一覧"という名称のリストがある。各アイテムは"件名""ノードパス""表示"プロパティを持つ。
"表示"プロパティはListBoxItemの"Visibility"とバインドされている。

1. 「東日本」をクリックする
2. "SelectedItemChanged"イベントが発生
3. "一覧"の中から"ノードパス"が「日本ー東日本」と一致もしくは「日本ー東日本」を含んでいるアイテムを探す
4. 条件が合うアイテムの"表示"プロパティを"Visible"、それ以外は"Collapsed"をsetする

発生している問題・エラーメッセージ

ただ、実際のアプリケーションではリストの全アイテム数が最大で10000件になる予定で、
3000件ほどで、ツリーを遷移したときにStackoverflow Exceptionが発生してしまっています。
(なおイベントを抜けた後の処理で発生しているようで、具体的な箇所については特定できてません。)

また件数が10件程度でも
・スクロールバーの挙動(サイズやスクロール時の)がおかしい
・ListBoxItemのVisibilityCollapsedを設定した項目が、実際にはHiddenの動きになっている(空白にはなっているもののItemの領域が存在しているため、謎の空白の空間が生まれる)
・以下のバインディングエラーが起きる

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ItemsControl', AncestorLevel='1''. BindingExpression:Path=HorizontalContentAlignment; DataItem=null; target element is 'ListBoxItem' (Name=''); target property is 'HorizontalContentAlignment' (type 'HorizontalAlignment')


など様々な問題が発生しており、そもそも根本的な実装が間違えているのかと思いました。

質問

上記のような機能を実装する場合、どのように実装するのがベストでしょうか?

各地域ごとに都道府県のリスト(一覧リスト)を持たせることも考えましたが、実アプリケーションではリアルタイムにリストのコンテンツが変動する点(同期の問題)や
例えば「東京」が含むツリーを考えると「日本」「東日本」「関東」すべてのリストに含ませる必要がある点から、非現実的だと思っています。

補足

ひとまず上記のバインディングエラーと謎の空白の空間については、
・StyleのVerticalAlignmentHorizontalAlignmentを明示的に設定する
VisibilityCollapsedのときにMargin=0にするトリガーを設定する
などを試しましたが解決には至りませんでした。

あまりソースを出したくないのでわかりにくい説明だとは思いますが、ご助言頂けますと幸いです。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • siksmtt

    2019/05/16 09:30

    draq 様
    地域毎にフィルタした結果のListを持たせるということでしょうか?

    キャンセル

  • draq

    2019/05/16 16:11

    そうです。ViewModelで完結することをViewのコードビハインドで処理するのは個人的に気持ち悪いです。
    バインドする県リストに本来必要の無いデータが多すぎるのもパフォーマンスに悪影響ありそうですし。

    キャンセル

  • siksmtt

    2019/05/16 17:33

    draq 様
    ご指摘ありがとうございます。色々調査しても解決の糸口が見えなかったので、ご提案の方法で試したところとりあえず各地域の遷移時の動作は理想の形になりました。
    質問文にもあるように、実際のアプリケーションではリアルタイムにコンテンツが変動するので、そちらも確認しますが
    ひとまずご提案の方法でテスト実装してみようと思います。

    キャンセル

回答 1

0

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/05/16 09:26

    Zuishin 様
    ご回答ありがとうございます。
    ListBoxについては既に仮想化を行っています。仮想化OFF状態での処理負荷とON状態での動作負荷を比べたところ、明らかな負荷差が見られるので仮想化については問題なくできていると思っています。

    TreeViewとの関連性も確認してみましたが、
    TreeViewがない状態でもスクロールバーがおかしい現象やバインディングエラーが発生しているので、関連性としては低いと思っています。

    キャンセル

  • 2019/05/16 09:38

    デバッグ依頼だったんですか? これだけの情報からは無理ですよ。

    まずは Model 層と ViewModel 層のテストを作成し、考えられるあらゆるデータにおいてそれが通るようにしてください。通らないならそこに問題があるのでしょうし、通るなら View 層のデバッグをするより仕方ないでしょう。

    キャンセル

  • 2019/05/16 10:52

    Zuishin 様
    誤解を招く言い方になり申し訳ありません。これだけしか情報がない中で「他に考えられる可能性はありますか」と聞くのも失礼かと思い、単純にご指摘頂いた内容への回答として返信いたしました。
    デバッグについては引き続き行いますが、もし代案などあればご指摘いただければ幸いです。

    キャンセル

  • 2019/05/16 10:55 編集

    代案も何も今の案がわからないので何とも言えませんが、ただバグが入ってるだけのような気がします。
    テストは作ってますか?

    キャンセル

  • 2019/05/16 17:30

    Zuihin 様
    テストを作成して発生条件などを絞ったところ、
    ScrollViewer.CanContentScroll="True" を設定し、且つModelの方で Visibility=Collapsedにすると発生するようでした。
    また軽くView層のテストも行ったところ、イベントを抜けた後で「循環が検出されました」というエラーが発生しており、View側の処理が永遠と走り続けるようでした。

    恥ずかしながらView層のテストはほぼしたことがなくどのように進めればいいのかもまだ分かっていないのですが、
    ひとまず仮想化と関わっている気がするので(仮想化OFFを避けるために)他の方法で対処しようと思います。
    ひとまずご報告になります。ご指摘ありがとうございました。

    キャンセル

同じタグがついた質問を見る

  • C#

    9062questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • WPF

    828questions

    Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

  • MVVM

    106questions

    MVVM(Model View ViewModel)は構築上のデザインパターンで、表現ロジック(ViewModel)によってデータ(Model)からページ(View)を分離させます。