問題タブ [delegatecommand]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
.net - DelegateCommand.CanExecuteChanged にサブスクライブできません
2 つの ViewModel があり、1 つに別の ViewModel が含まれています。内側のものにはMicrosoft.Practices.Prism.Commands.DelegateCommand
と呼ばれるものがありPrintCommand
ます。CanExecuteChanged
このコマンドのイベントにサブスクライブすることが望ましいです。この部分は通常どおり実装されます。
問題は、このサブスクリプションが機能しないことです。逆コンパイルCanExecuteChanged
すると次のようになります。
デバッグすると、サブスクライバー オブジェクトがまだ存在していても、サブスクリプション後のいくつかの手順の後、_canExecuteChangedHandlers
アクティブなハンドラーが含まれていないようです。
ちょっと気になるのですが、どうしてこうなったのですか?
c# - MVVM ICommand.CanExecute パラメーターに以前の値が含まれている
通常のプロパティの代わりにネストされたプロパティが使用されている場合、 ICommand.CanExecutes に常に新しい値ではなく以前の値が含まれる理由を理解するのに苦労しました。
問題は以下で説明されていますが、ビューモデルでプロパティを作成し、モデルの対応するプロパティにフックする何らかの形式の「ファサード」パターンを使用する以外に、これを修正する方法を真剣に理解できません。
または、いまいましい CommandManager.RequerySuggested イベントを使用します。これが最適ではない理由は、メニューを数えるだけで 30 を超えるコマンドがビューに表示され、何かが変更されるたびにすべての CanExecute が更新される場合、すべてのメニュー項目/ボタンが更新されるまでに数秒かかるためです。以下の例をコマンド マネージャーと共に 1 つのコマンドとボタンだけで使用しても、ボタン自体を有効/無効にするのに約 500 ミリ秒かかります。
私が考えることができる唯一の理由は、CanExecute が起動される前に CommandParameter バインディングが更新されないことです。それについては何もできないと思います。
前もって感謝します :!
例えば
この基本的なビューモデルがあるとしましょう
そしてこのモデル
私の見解では、このテキストボックスとボタンがあります。
テキストボックスに何かを入力するたびに CanExecute が呼び出されますが、パラメーターは常に前の値に設定されます。テキストボックスに 'H' と書くと、パラメータを NULL に設定して CanExecute が起動されます。次に「E」と書きます。テキストボックスに「HE」が含まれ、CanExecute が再び起動します。今回はパラメータを'H'のみに設定。
奇妙な理由で、パラメーターは常に以前の値に設定され、Project.Text を確認すると「HE」に設定されていますが、パラメーターはまだ「H」にのみ設定されています。
コマンドパラメータを
と Textbox.Text へ
すべてが完璧に機能します。CanExecute パラメーターには、以前の値ではなく常に最新の値が含まれます。
c# - RaiseCanExecuteChanged はコンパイルされた exe では機能しないが、デバッグ時には機能する
何が原因なのかまったくわかりません。
背景: Prism フレームワークの使用
- 私はにバインドされたボタンを持っています
DelegateCommand
- 電話する
RaiseCanExecuteChanged
Visual Studio でデバッグ モードでアプリを起動すると、すべてが完全に機能します。アプリは完璧に動作します。
その後、.exe 経由でアプリを開くと、RaiseCanExecuteChanged
メソッドが呼び出されていません。なぜそうなるのか、私にはわかりません。他の誰かが同様の問題に遭遇しますか?
編集: .exe を介して最初にアプリを開くと、RaiseCanExecuteChanged
が呼び出されます (私のコンストラクターで設定したためViewModel
)。ただし、再度呼び出されることはありません。
必要な場合のコード:
IsEnabled
私は必死になって、バインドしたボタンにプロパティを入れようとしましたCanExecuteButton
が、役に立ちませんでした。
c# - Prism DelegateCommands がスレッド例外を引き起こすことがあるのはなぜですか?
以下の例では Prism 6.1 の DelegateCommand を使用していますが、5.0 でも同じ問題が発生しました。
次のビューモデルを使用します (ビューは省略され、2 つのボタンのみで構成されます):
ActiveCommand が最初に呼び出されると、次の例外が発生します。
タイプ 'System.InvalidOperationException' の例外が WindowsBase.dll で発生しましたが、ユーザー コードで処理されませんでした
追加情報: 別のスレッドがこのオブジェクトを所有しているため、呼び出しスレッドはこのオブジェクトにアクセスできません。
これは、私が知る限り、「UI スレッドを使用していない場合、Wpf コントロールと対話することは許可されていません」という標準的な例外です。これは、メソッドの要約と矛盾しているようです。
UI スレッドで Prism.Commands.DelegateCommandBase.CanExecuteChanged を発生させ、すべてのコマンド呼び出し元がコマンドを実行できるかどうかを確認するために再クエリできるようにします。
また、過去に非 UI スレッドからこのメソッドを呼び出すことに問題はありませんでした。
さらに奇妙なことに、最初に TestCommand が発生すると、ActionCommand が正常に動作し始めます。確認したところ、Task.Run ブロック内のコードはすべての場合において非 UI スレッドで実行されています。
残念ながら、実際のコードでこれを回避策として使用することはできません。ワーカー スレッドが呼び出す前に UI スレッドで RaiseCanExecuteChanged を呼び出そうとしましたが、役に立ちません。
RaiseCanExecuteChanged がこのように動作する理由はありますか? 修正または回避策はありますか?