0

コンストラクターを介して割り当てられた、WPF アプリケーションに関連付けられた MainViewModel を持つ MainView があります。

アプリ >起動 uri > MainWindow.xaml

    public MainWindow()
    {
        InitializeComponent();

        var viewModel = new MainViewModel();

        DataContext = viewModel;
    }

My MainView には、MainView でクリックされたボタンに基づいて非表示および表示されるネストされたビューまたは子ビューが最大 4 つ保持されます。そのため、MainView の各ボタンに割り当てられたコマンド バインディングを介して更新されるバインディングを介して可視性プロパティを切り替えます。

ネストされた各ビューには関連付けられたビューモデルがありません。子ビューで見つかったすべてのバインディングは、MainViewModel で情報を見つけます。そのため、バインディング システムはアプリの UI ツリーを調べて、親の「MainView」に ViewModel が関連付けられていることを確認します。

したがって、全体として「ONE」-> ViewModel があります。これは問題なく動作しているように見えますが、予想どおり、この VM は大きくなり、リファクタリングが必要です。文脈上、保持すべきではない情報を保持します。しかし、これは証明概念の適用です。だから私はそれをシンプルに保ち、それが実行可能であることを確認することにしました.

問題:

空のビュー モデルに空のビューを割り当てようとすると、出力ウィンドウにバインド エラーが表示され、予想どおり、奇妙で壊れた動作に気付きました。これは意味がありません...ネストされたビューコントロールで見つかったバインディングを処理する方法をWPFに知らせる、より明確で簡潔な方法はありますか? 上記のように、各ビューのコンストラクターが対応する VM を自分自身に割り当てた場合、これは論理的に理にかなっているため、機能するはずだと思いました。残念ながら、MainView のすべてのボタンは、対応するビューをオンにして他のビューを非表示にするように指定されている場合、ViewModel が関連付けられていると機能しなくなります。一部のボタンでは機能し、他のボタンでは機能しませんか? これは本当に奇妙ですか?

4

1 に答える 1

0

上記の私の回答で述べたように、問題は、WPF バインディング システムが実行時にバインディングを解決するのに苦労していたことです。メイン ビューには、関連するビュー モデルがインスタンス化され、メイン ビュー コンストラクターを介して割り当てられます。このパターンは、MainView にも含まれるすべての入れ子になったビューに対して繰り返されます。

デフォルトでは、暗黙のバインディング構文を使用する傾向があります。つまり、ソースを明示的に指定しなくても、バインディング システムはバインディングで指定した名前を解決しようとします。したがって、それはすべて暗示的であり、何も明示的に設定されていません!

ネストされた各ビューをアップグレードして独自のビュー モデルを持つようにすると、バインディングの自動検出/解決が少しおかしくなり、探しているプロパティの場所をバインディング システムに明示的に伝えていないため、出力ウィンドウのバインディング エラーが発生します。

これは、ネストされたビュー --> ビューモデルでバインド式を解決しようとしていることが出力ウィンドウに示されているため、予期しない動作につながります。実際にその VM を覗いてみたら IS EMPTY!

したがって、バインディング構文内でソース プロパティを明示的に設定しない場合、バインディング システムが優れていることは明らかです。自分で物事を見つけるのに十分賢いです。私の場合、どこで物を見つけるかがわからなかったので、追加の助けが必要でした.

解決:

  1. MainView コンストラクターで MainViewModel のコンストラクター宣言を削除します。
  2. ViewModels 名前空間の xmlns を MainView.xaml にスコープします。
  3. MainView .xaml 内にウィンドウ リソースを作成する
  4. リソースにキーを与えます。
  5. MainView xaml ファイル内のすべてのバインディングをアップグレードして、ソース プロパティを含めます。
  6. ソース プロパティに、手順 4 で設定した ViewModel キー値を指す静的リソース バインディングを指定します。
  7. MainView に関連付けられている ViewModel を参照するバインディングに対してのみ、手順 6 を実行します。
  8. ネストされたすべてのビューはそのままにしておき、独自の xaml ファイルで独自のバインディングを処理する必要があります。MainView は単にそれらをインスタンス化し、UI に配置します。私の場合はそうでした。ネストされたビューに関するバインディングはもうありませんでした。MainView.xaml ファイルに存在するすべてのバインディングは、MainViewModel.cs 内のデータを参照していました。これにより、問題を表示するときに非常に簡単になります。

なんらかの理由でエディターがぎこちなかったので、サンプル コードを省略することにしましたが、上記の手順は、私が行った手順に従うのに十分な説明です。上記は私のために働いたものです。

この問題を要約する別の方法

  • ほとんどの本は短いバインディング構文を教えています
  • 複数のデータ コンテキストが利用可能な場合はどうなりますか?
  • バインディング システムは、短い手のバインディング式をどのように解決するかをどのように認識していると思われますか。
于 2012-04-26T12:12:35.657 に答える