まぐらぼ

日々の雑記を書いています。

ストアアプリでは「ViewModelからViewを操作する」が出来ないのか?

TextBoxとViewModelプロパティをデータバインドして、ViewModel内でプロパティを操作するとTextBoxに反映されます。これがTextBoxではなくListViewの場合は反映されません。TwowayでもOnewayでも同じ結果でした。

//こう書くとListViewの表示は消えます。
ListViewData = new List<string>(); 
ListViewData = null;// これも消える
//ListViewの表示は消えない
ListViewData.Clear();
ListViewData.RemoveAt(1);//これも結果は反映されない

こんな感じで一度別のListオブジェクトへ退避させてプロパティにセットし直してもダメですね。

_lvdata_b = _lvdata;
_lvdata_b.RemoveAt(1);
ListViewData = _lvdata_b;
OnPropertyChanged("ListViewData");

(というか、これストアアプリ基盤のバグじゃないのか?) 2014/07/01追記 ObservableCollection<>使用で解決しまいた。

だから、ViewModelからViewを操作する方法を試そうと思ったのですが、この方法はWPFのトリガー機能を使うためストアアプリだと実装できないみたいですね。

仕方がないので検索してみると、こんなのがありました。「ViewModelからViewへのメッセージング手法」によれば、ViewModelからView操作の方法は3つあります。
1. インターフェースを準備する
2. Viewにコマンドを実装する(ReverseCommand)
3. Messanger (MVVM Light toolkit )
4. Triger & Action (これがストアアプリではダメ)

(4)は無理。とりあえず(1)を試しました。View実体はこのように記述しました。実体を掴む時点でI/Fを使うメリットが無い気がするのでI/Fは省略してViewのメソッドを呼ぶ方式で使います。(I/Fは自動単体テストのためらしい)(3)MVVM Light toolkitはストアアプリでは試したこと無いので週末にやってみます。

        // ViewModelからViewのインスタンスをつかむ
        private MainPage ViewInstance {
            get {
                Frame rootFrame = Window.Current.Content as Frame;
                if (rootFrame.CurrentSourcePageType.Name == "MainPage") {
                    return (MainPage)rootFrame.Content;
                }           
                return null;
            }
        }

正直、たかがUserInterfaceでここまで苦労するならMVVMは意味ないと思います。データバインディングは便利だし、デザイナだけでViewを構築できるメリットは認めますが、導入コスト、他メンバ教育コストが高すぎて現実的ではないと感じます。