none
UserControlについて RRS feed

  • 質問

  • A画面(一覧画面)

    B画面(A画面で選択した行の詳細画面)

    の2画面をUserControlの切り替えで処理しようと思っています。

     

    MainWindowにUserControl用のプロパティをバインドしています。

    このプロパティを切り替えることにより、A画面→B画面、B画面→A画面を実現しております。

     

    処理自体は、なんとかできているのですが、レスポンスが遅いのが問題点になっています。

    特に、B画面→A画面が極端に遅いです。(A画面は15レコード程度しかありません)

    なお、B画面→A画面の際に、A画面のインスタンス化は再度しておりません。

    どうも、画面を一度隠してしまう(プロパティの切り替え)と、再バインド等により、Viewの表示に時間がかかっている気がします。

     

    そもそもの作りが悪いような気もしますので、皆様のご意見を聞かせて頂けますでしょうか?

    2011年3月28日 2:44

回答

  • Prismベースで画面遷移を作ってみました。画面遷移の部分にはFrameを使っています。コードは以下からダウンロードできます。

    http://code.msdn.microsoft.com/MVVM-WPF-e1c3c356


    かずき Blog:http://d.hatena.ne.jp/okazuki/ VS 2010のデザイナでBlendのBehaviorをサポートするツール公開してます。 http://vsbehaviorsupport.codeplex.com/
    • 回答としてマーク すねお 2011年4月14日 4:23
    2011年4月1日 13:22

すべての返信

  • IDE で実行すると非常に遅くとも、生成された実行ファイル(.exe)を直接実行すると劇速な場合があります。
    ビルドした EXE ファイルを直接実行して試してみるとどうでしょうか?

     


    ひらぽん http://d.hatena.ne.jp/hilapon/
    2011年3月28日 3:30
    モデレータ
  • ありがとうございます。

     

    試してみましたが、一緒でした。

    2011年3月28日 4:38
  • > MainWindowにUserControl用のプロパティをバインドしています。
    > このプロパティを切り替えることにより、A画面→B画面、B画面→A画面を実現しております。

    ちょっとわかりにくいので確認ですが、
    UserControl のプロパティをバインドして A画面 <-> B画面 の切り替えというのは
    「画面 = Window 」 じゃなくて 「画面 = UserContorl」 の切り替えをしているということですか?

    あと開発環境と WPF のバージョンも教えて頂きたいです。

     


    ひらぽん http://d.hatena.ne.jp/hilapon/
    2011年3月28日 4:55
    モデレータ
  • 色々すみません。

    開発環境:VS2010Pro

    WPF:4

    となります。

     

     「画面 = UserContorl」の切り替えになります。

    したがって、MainWindowは、ずっと見えっぱなし状態であり、

    中身だけが変化していく方法です。

     

    2011年3月28日 5:13
  • > 「画面 = UserContorl」の切り替えになります。
    > したがって、MainWindowは、ずっと見えっぱなし状態であり、中身だけが変化していく方法です。

    実は私も似たようなことをしております。

    ユーザーがクリックするボタンの種類により複数の UserContorl の表示を切り替えているのですが、
    XP 開発マシンの IDE 上で実行すると全体的に動作がもっさりしますが
    生成した exe ではパフォーマンスに問題は見られません。

    もっともこの Window では ActiveX を使っている関係上、
    ほとんどバインドは使わずイベントハンドラで処理を行っていますが・・・

    いずれにせよ UserContorl の表示を切り替える程度でパフォーマンスに影響出るのは考えにくいです。
    再バインド・・・・う~ん・・・、なにか他にも考えられる原因、思いつきませんか?


    ひらぽん http://d.hatena.ne.jp/hilapon/
    2011年3月28日 5:59
    モデレータ
  • 元々、UserContorlでは無く、2つのWindowで処理してました。

    A画面→B画面:このタイミングでA画面をHide

    B画面→A画面:このタイミングでA画面をShow

    Windowベースの場合、レスポンスは特に問題ありませんでしたが、

    Hide・Showでの処理で画面がチラチラするのが嫌で、UserContorlを試してみたという経緯です。

     

    UserContorlを用いるにあたって、当然処理は一緒にしております。

    A画面→B画面→A画面

    では、後者のA画面がloadされており、このタイミングで再バインドされているのではないか?と疑っています。

    ステップインで実行していく限りでは、特に処理が止まる部分もありません。

    単純に処理が終わってからViewが表示される時間が一番長いです。

     

    2011年3月28日 6:42
  • すねおさんの最初の質問を読むと

    > なお、B画面→A画面の際に、A画面のインスタンス化は再度しておりません。

    と書かれておられ、この時点では再表示しているだけのように受け取れますが、最後のレスを読むと

    > A画面→B画面→A画面
    > では、後者のA画面がloadされており、このタイミングで再バインドされているのではないか?と疑っています。

    と、新たに A画面のインスタンスを作り、Load しているようにも読めます。
    この A画面→B画面→A画面 の切り替えはどのように行っておられるのでしょうか?

    ちなみに私の作った画面ですと、一度インスタンスを生成した後は

    UserControlA.Visibility = Visibility.Hidden
    UserControlB.Visibility = Visibility.Visible

    と Visibility プロパティの設定を変えて表示/非表示を切り替えてるだけなので、特にインスタンス化の際のオーバーヘッドや再バインドは発生しておらず、ユーザーコントロールの切替におけるパフォーマンスの問題は全く生じておりません。


    ひらぽん http://d.hatena.ne.jp/hilapon/
    2011年3月28日 8:38
    モデレータ
  •     public class MainWindowViewModel : ViewModelBase
        {

        //A画面のView
            public CustomerListView CustomerListView;

        //A画面のViewModel
            public CustomerListViewModel CustomerListViewModel;

        //B画面のView

            public CustomerView CustomerView;

        //B画面のViewModel
            public Customer ViewModel CustomerViewModel;

        //バインドするプロパティ

            public UserControl UserControl { get; set; }

            public A()

           {           

                   UserControl = CustomerListView;
                   RaisePropertyChanged(() => UserControl);
            }

            public B()

            {

                     UserControl = CustomerView;
                     RaisePropertyChanged(() => UserControl);
            }

        }

     

    MainWindowにUserControl(プロパティ)を置き、インスタンス化したViewをメソッドをかえしてセットします。

    このプロパティがViewからバインドされており、 RaisePropertyChangedにより、動的に表示が切り替わる仕組みです。

    よって、インスタンス化は最初の1回だけとなります。

    何度もすみませんが、宜しくお願い致します。

    2011年3月28日 9:03
  • ・・・なるほど、ViewModel から View(この場合、UserControl) を提供していると・・・
    私も MVVM の初心者ですが、このクラスを見ると、なにか違うような気がするのは気のせいでしょうか(汗

    私なら View(この場合 XAML) に二つの UserControl を配置し、ViewModel 側にはどちらの UserControl を表示するかのプロパティを設け、View 側にこのプロパティをバインドさせるようにしますが。


    ひらぽん http://d.hatena.ne.jp/hilapon/
    2011年3月28日 9:47
    モデレータ
  • そうですね。

    自分でも、何か違うような気がしてます。

    私も初心者でして、あれこれ試行錯誤した結果、この方法にたどり着きました(こんなのでも。。)。

     

    やっぱり、作りがおかしいんでしょうかねぇ。

    2011年3月28日 10:25
  • 一般的に、ViewModelがViewのインスタンスを保持してはいけません。保持してしまえばコードビハインドに書くこととほとんど変わらないでしょう。ただ、あまり厳密に考えすぎると敷居が高くなってしまいますので、最初から厳格にMVVMで構築して下さいとも言いませんし、必ずMVVMで構築して下さいと強く言うつもりもありません。個人的には少しずつで良いと思います。ただ、きちんとしたMVVMで最初から組めなくても、概念はしっかり押さえて下さい。
    MVVMで画面を切り替える例ですが、以下がそのものだと思います。有名な記事ですし、少し前まではほとんどこの文書ぐらいしか無かったと思います。私もMVVMを学ぶときに最初に読みました。

    Model-View-ViewModel デザイン パターンによる WPF アプリケーション
    http://msdn.microsoft.com/ja-jp/magazine/dd419663.aspx

    実際にはこの記事だけではとても全てをカバーできないのですが、そこからMVVMの概念を実現するための手段を少しずつ学んでいけば良いと思います。いずれテクニカル的にMVVMのフレームワークがVisual Studioでサポートされる日が来るかもしれませんが、それでも悩んで、もがいたことはきっと無駄にならないと思います。

     


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    2011年3月28日 11:32
    モデレータ
  • ありがとうございます。

     

    私も、これを使っていろいろ学習しました。

    MVVMにこだわりすぎず、開発規模にあったやり方、つまり生産性を考慮しなければなりません。

    まだ、具体的にどうこう言える立場ではありませんが。。

     

    みなさん、ありがとうございました。

    もう少し、ねばってあがいてみます。

     

    2011年3月29日 11:39
  • Prismベースで画面遷移を作ってみました。画面遷移の部分にはFrameを使っています。コードは以下からダウンロードできます。

    http://code.msdn.microsoft.com/MVVM-WPF-e1c3c356


    かずき Blog:http://d.hatena.ne.jp/okazuki/ VS 2010のデザイナでBlendのBehaviorをサポートするツール公開してます。 http://vsbehaviorsupport.codeplex.com/
    • 回答としてマーク すねお 2011年4月14日 4:23
    2011年4月1日 13:22