none
WPF(Prism6)、MVVMでのNavigation使用時のUserControlのViewModelのコンストラクタ実行方法について RRS feed

  • 質問

  • WPF(Prism6)、MVVMでのNavigation使用時のViewModelのコンストラクタの実行方法について、初歩的な質問ですみませんが
    わからなくて困ってます。

    GitHubのPrismLibrary / Prism-Samples-Wpf と参考書を参考にして、開発ベースを作成しています。
    自身の環境で、基本で使用することになるBootstrapper, DelegateCommand, Navigation は動作確認済みです。
    また、Entity Frameworkを使用してます。


    (Window構成)
    MainWindow.xaml (Window)
    Sub.xaml (UserControl)


    ViewModelで実行するメソッドの動作確認を行いたいため、

    MainWindowからRegionManagerで、移動先のViewのViewModelにてコンストラクタでブレークポイントを貼り、停止したいのですが、SubViewModelではコンストラクタで停止してくれないため、どのようにすればよいでしょうか。


    public class SubViewModel : BindableBase, INotifyDataErrorInfo{
        public SubViewModel(IRegionManager regionManager) {
    
            _regionManager = regionManager;
            NavigateCommand = new DelegateCommand<string>(Navigate);
            
            this.errorsContainer = new ErrorsContainer<string>(OnErrorsChanged);
            
            SearchCommand = new DelegateCommand(executeSearch);
            ClearCommand = new DelegateCommand(executeClear);
            UpdateCommand = new DelegateCommand(executeUpdate);
            // Updateは .ObservesPropertyを使用予定
            
            DeleteCommand = new DelegateCommand(executeDelete);
            
            this.M_Samples = new M_Samples();
            this.Items = new ObservableCollection<M_Samples>();
            this.SelectedItem = new M_Samples();
            
            // コンストラクタで実行されるViewModelメソッドの動作確認をしたい(executeSearch, Clear, ... など)
            Clear();
            executeSearch();
            
            // コンストラクタで実行しないメソッドはメソッド内に直接ブレークポイントを貼ると思う
        }
        
        public SubViewModel() {
            // RegionManagerを使用するとここは実行されない?
        }
    
        // ... 記載省略
    
    }





    • 編集済み yuchan01 2018年2月19日 8:24
    2018年2月18日 1:20

回答

  • 一時的に引数有の方のコンストラクタをコメントアウトしておけば呼ばれませんか?(そのあとでViewに繋いでくれるかまでは判りませんが)

    ふつうのコンストラクタは

    • 引き数有りは、引数無しコンストラクタと同じ処理をしたうえで追加の処理をする
    • 引き数無しは、引数有りのコンストラクタに既定の初期値を与えた場合の処理をする

    のどちらかのはずですから、まとめてしまえばいいのでは?

    引き数無しと引数有りのコンストラクタを一つにまとめて引数のオプション省略指定を見て処理を分ける場合

    public class SubViewModel : BindableBase, INotifyDataErrorInfo
    {
        public SubViewModel(IRegionManager regionManager = null)
        {
            if (regionManager != null)
            {
                //regionManager有りの場合の処理
            }
            else
            {
                //引数nullの場合の処理
            }
        }
        //public SubViewModel()
        //{
        //    引数の無いコンストラクタは定義しない(混乱の元なので)
        //}
    }

    あるいは、引数有りのコンストラクタから引数無しコンストラクタを呼ぶ場合

    public class SubViewModel : BindableBase, INotifyDataErrorInfo
    {
        public SubViewModel(IRegionManager regionManager) : this()
        {
                //regionManager有りの場合のみ実行する処理
        }
    
        public SubViewModel()
        {
            // 引数無しと引数有の両方で実行する処理
        }
    }


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク yuchan01 2018年2月18日 6:59
    • 回答としてマークされていない yuchan01 2018年2月18日 6:59
    • 回答としてマーク yuchan01 2018年2月19日 15:36
    2018年2月18日 5:21

すべての返信

  • 一時的に引数有の方のコンストラクタをコメントアウトしておけば呼ばれませんか?(そのあとでViewに繋いでくれるかまでは判りませんが)

    ふつうのコンストラクタは

    • 引き数有りは、引数無しコンストラクタと同じ処理をしたうえで追加の処理をする
    • 引き数無しは、引数有りのコンストラクタに既定の初期値を与えた場合の処理をする

    のどちらかのはずですから、まとめてしまえばいいのでは?

    引き数無しと引数有りのコンストラクタを一つにまとめて引数のオプション省略指定を見て処理を分ける場合

    public class SubViewModel : BindableBase, INotifyDataErrorInfo
    {
        public SubViewModel(IRegionManager regionManager = null)
        {
            if (regionManager != null)
            {
                //regionManager有りの場合の処理
            }
            else
            {
                //引数nullの場合の処理
            }
        }
        //public SubViewModel()
        //{
        //    引数の無いコンストラクタは定義しない(混乱の元なので)
        //}
    }

    あるいは、引数有りのコンストラクタから引数無しコンストラクタを呼ぶ場合

    public class SubViewModel : BindableBase, INotifyDataErrorInfo
    {
        public SubViewModel(IRegionManager regionManager) : this()
        {
                //regionManager有りの場合のみ実行する処理
        }
    
        public SubViewModel()
        {
            // 引数無しと引数有の両方で実行する処理
        }
    }


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク yuchan01 2018年2月18日 6:59
    • 回答としてマークされていない yuchan01 2018年2月18日 6:59
    • 回答としてマーク yuchan01 2018年2月19日 15:36
    2018年2月18日 5:21
  • 返信内容書き直しました。


    ご回答ありがとうございます。

    引数有り無しのコンストラクタの使用方法について、とても参考になりました。

    しかし、一時的に引数有の方のコンストラクタをコメントアウトしても呼ばれませんでした。
    通常コンストラクタは呼ばれると思いますが、
    RegionManagerを使用して、ブレークポイントを貼ると

    MainWindow.xaml(Window)のMainWindowViewModelのコンストラクタでは停止しますが、
    Sub.xaml(UserControl)のコードビハインドのInitializeComponent()までは動いてますが、

    その後、SubViewModelのコンストラクタで停止しないので、実行していないような気がします。
    ※Window内のUserControlなのでコンストラクタが実行しない?


    PrismLibrary/Prism-Samples-Wpfの「17-BasicRegionNavigation」 でも同様の状態でした。

    ここから参考にしました → https://github.com/PrismLibrary/Prism-Samples-Wpf/tree/master/17-BasicRegionNavigation

    • 編集済み yuchan01 2018年2月18日 11:19
    2018年2月18日 7:09
  • 大変申し訳ございませんが、プログラムの綴り間違いを見つけ、

    コンストラクタを実行することができました。

    gekkaさん ありがとうございました。

    2018年2月19日 15:36