ICommandインターフェイスを使用し、CommandとCommandParameters(または単にコマンド)を介してコントロールにバインドすると、ボタン/コントロールが自動的に有効/使用されている値が変更されると無効になります(CanExecuteを呼び出します)。ICommandでUpdateCanExecute/CanExecuteをマルチプレックスモデル用に簡単に管理する方法
答えて
ここに興味のある人は、RelayCommandを介してICommandを常に必要に応じて強制的に更新する少しのレポがあります。これは実用的なIMOになるビューで余分な作業を必要としません。
中継コマンドは容易のICommandインターフェースを自動化する方法の一例であり、全ての溶液修正することを意味するものではありません。
ここRelayCommand
public class RelayCommand : ICommand
{
private readonly RelayCommandBindings relayCommandBindings;
public event EventHandler CanExecuteChanged;
internal RelayCommand(RelayCommandBindings relayCommandBindings)
{
this.relayCommandBindings = relayCommandBindings;
relayCommandBindings.BindingModel.PropertyChanged += (s, e) =>
{
if (relayCommandBindings.BindingProperties.Any(p => p == e.PropertyName))
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
};
}
public bool CanExecute(object parameter) => (relayCommandBindings.CanExecuteChecks?.All(p => p.Invoke(parameter))).GetValueOrDefault();
public void Execute(object parameter) => relayCommandBindings?.Execute?.Invoke(parameter);
}
ここでは、ここでRelayCommandBindings
internal class RelayCommandBindings
{
public Action<object> Execute { get; set; }
public IEnumerable<Predicate<object>> CanExecuteChecks { get; set; }
public INotifyPropertyChanged BindingModel { get; set; }
public IEnumerable<string> BindingProperties { get; set; }
}
ですViewModelに
public class MultiplexViewModel : INotifyPropertyChanged
{
private const string NoName = "(no name)";
private bool isActive;
private bool isActiveChanging;
private string name;
private readonly MultiPlexModel multiPlexModel;
private readonly SynchronizationContext synchronizationContext;
public MultiplexViewModel()
{
multiPlexModel = new MultiPlexModel();
synchronizationContext = SynchronizationContext.Current;
var bindingProperties = new[]
{
nameof(IsActive),
nameof(IsActiveChanging)
};
var setNewNameBindings = new RelayCommandBindings()
{
Execute = async (obj) => await multiPlexModel.StartMultiplexModelAsync(obj.ToString()),
CanExecuteChecks = new List<Predicate<object>>
{
(obj) => IsValidName(obj?.ToString()),
(obj) => IsActive == false,
(obj) => IsActiveChanging == false
},
BindingModel = this,
BindingProperties = bindingProperties
};
var stopMultiplexBindings = new RelayCommandBindings()
{
Execute = async (obj) => await multiPlexModel.StopMultiplexModelAsync(),
CanExecuteChecks = new List<Predicate<object>>
{
(obj) => IsActive == true,
(obj) => IsActiveChanging == false
},
BindingModel = this,
BindingProperties = bindingProperties
};
SetNewNameCommand = new RelayCommand(setNewNameBindings);
StopMultiplexCommand = new RelayCommand(stopMultiplexBindings);
multiPlexModel.PropertyChanged += (s, e) => GetType().GetProperties().Where(p => p.Name == e.PropertyName).FirstOrDefault()?.SetValue(this, multiPlexModel.GetType().GetProperty(e.PropertyName).GetValue(multiPlexModel));
}
public event PropertyChangedEventHandler PropertyChanged;
public void Notify([CallerMemberName] string propertyName = "") => synchronizationContext.Post((o) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)), null);
public bool IsActive
{
get { return isActive; }
private set
{
isActive = value;
Notify();
}
}
public bool IsActiveChanging
{
get { return isActiveChanging; }
private set
{
isActiveChanging = value;
Notify();
}
}
public string Name
{
get { return string.IsNullOrEmpty(name) ? NoName : name; }
private set
{
name = value;
Notify();
}
}
private bool IsValidName(string name) => (name?.StartsWith("@")).GetValueOrDefault();
public RelayCommand SetNewNameCommand { get; private set; }
public RelayCommand StopMultiplexCommand { get; private set; }
}
ここでは、モデル
public class MultiPlexModel : INotifyPropertyChanged
{
private bool isActive;
private bool isActiveChanging;
private string name;
public event PropertyChangedEventHandler PropertyChanged;
public void Notify([CallerMemberName] string propertyName = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
public bool IsActive
{
get { return isActive; }
private set
{
isActive = value;
Notify();
}
}
public bool IsActiveChanging
{
get { return isActiveChanging; }
private set
{
isActiveChanging = value;
Notify();
}
}
public string Name
{
get { return name; }
private set
{
name = value;
Notify();
}
}
public async Task StartMultiplexModelAsync(string newName)
{
await Task.Run(async() =>
{
if (IsActiveChanging)
return;
IsActiveChanging = true;
await Task.Delay(2000);
Name = newName;
IsActive = true;
IsActiveChanging = false;
});
}
public async Task StopMultiplexModelAsync()
{
await Task.Run(async() =>
{
if (IsActiveChanging)
return;
IsActiveChanging = true;
await Task.Delay(2000);
Name = string.Empty;
IsActive = false;
IsActiveChanging = false;
});
}
}
です
そして、ここに新しい名前を設定するために
<UserControl.DataContext>
<ViewModels:MultiplexViewModel />
</UserControl.DataContext>
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBlock Text="Auto Relay Command Example"
Margin="12, 40, 12, 12"
FontSize="32"
TextWrapping="Wrap" />
<TextBlock Text="The purpose of this application is to demonstrate a method for automatically activating CanExecute in ICommand. This automatically triggers buttons to become enabled/disabled based on various binding properties at once."
Margin="12"
TextWrapping="Wrap" />
<TextBlock Text="The name of the multiplex can only be set once if it starts with the @ symbol and the multiplex is not active."
Margin="12"
TextWrapping="Wrap" />
<TextBlock Text="The multiplex is started when the name is being properly set. At that time the multiplex cannot be altered... once it is set it cannot be reset until it has been stopped."
Margin="12"
TextWrapping="Wrap" />
<TextBlock Text="There is no code behind, triggers, converters, or other tricks used to make this work. This is purely binding to the commands in the ViewModel. The magic is in the RelayCommand and RelayCommandBindings in the ViewModels namespace."
Margin="12"
TextWrapping="Wrap" />
<TextBox Name="TextBoxName"
Text="{Binding Name, Mode=OneWay}"
Margin="12" />
<Button Content="Set New Name"
Margin="12"
Command="{Binding SetNewNameCommand}"
CommandParameter="{Binding Text, ElementName=TextBoxName}" />
<Button Content="Stop Multiplex"
Margin="12"
Command="{Binding StopMultiplexCommand}" />
<StackPanel Margin="12">
<TextBlock Text="Multiplex Changing" />
<TextBlock Text="{Binding IsActiveChanging}" />
</StackPanel>
<StackPanel Margin="12">
<TextBlock Text="Multiplex Active" />
<TextBlock Text="{Binding IsActive}" />
</StackPanel>
<StackPanel Margin="12">
<TextBlock Text="Multiplex Name" />
<TextBlock Text="{Binding Name}" />
</StackPanel>
</StackPanel>
イメージ---------
ここでボタンが有効になっているビュー..です。
ここでは...ここで名前が設定され、[停止]ボタンが有効になっている...
、一旦停止を活性化しながら、ここではボタンが再び無効になっている
、ビューは開始に戻ります。この例では
あなたはビューでは、IMO、あるべき姿を結合まっすぐ進むのコマンドを使用して、ビューのトーンを設定するさまざまなプロパティを参照してください。ちょうどこれが助けになると思った...
@PeterDuniho人々がGit Repoを使いたいのであれば、気にする必要はありません。私は例を書いて時間を費やしていたので、純粋なMVVMアーキテクチャーでCanExecuteを修正する複数の変数を処理しようとしている人を助けるためだけにデモが動作するのを見ることができました。レポは単に洞察力/助けを提供することに過ぎず、他の目的のために維持することは全く役に立たない。 –
- 1. Symfonyで簡単にユーザを管理する最良の方法
- 2. アプリのアプリケーション設定管理で簡単にする方法は?
- 3. 複数のJSファイルを簡単に管理する方法は?
- 4. package.jsonを簡単に管理する方法
- 5. Yii2で簡単な管理パネルを実装する方法
- 6. Magentoで簡単な管理モジュールグリッドを作成する方法は?
- 7. 簡単な管理フォームでフォームエラーを取得する方法
- 8. iOS:RESTエンドポイントを管理する簡単な方法
- 9. webformsまたはmvcでデータフローを簡単に管理する
- 10. カレンダー管理モジュールをDjangoプロジェクトに簡単に組み込む方法
- 11. GitHubで複数のブランチを管理する簡単な方法は?
- 12. ココアで簡単なアプリケーションモーダルダイアログを表示および管理する方法
- 13. 複数のコンピュータ間でソロプロジェクトを管理する簡単な方法
- 14. web2pyプロセスへのリモート管理アクセスを設定する最も簡単な方法
- 15. 簡単な管理者:フォームのコレクション
- 16. 簡単な文書管理システムとAPI
- 17. 簡単なプロジェクト管理/バグ追跡アプリケーション?
- 18. jsonで簡単に印刷する方法簡単なJavaライブラリ
- 19. GitやBazaarでコードを管理する方が簡単ですか?
- 20. Railsで簡単なステータスを管理する
- 21. ログイン/登録/管理エリアタイプのWebサイトをJavaで簡単に構築する方法はどちらですか
- 22. djangoの管理サイトでmulitfieldを簡単にフィルタリングする方法はありますか?
- 23. Djangoの管理者の外でfilter_horizontalを使用する最も簡単な方法
- 24. Swiftで簡単に配列に画像を追加する(簡単な方法)
- 25. 簡単な管理のために複数のファイルにコードを分割する
- 26. ブートストラップの簡単な管理/ユーザシステムについてのアドバイス
- 27. javascriptを使用して管理者としてバッチを実行する簡単な方法
- 28. VIM:VimからVisual Studioソリューション/ makefileプロジェクトを簡単に管理する方法はありますか?
- 29. ソース管理のローカルWeb.configに特定の変更を簡単に加える方法
- 30. gitを使って簡単なバージョン管理システムを実装するには?
Stack Overflowに関する質問は、適切な時に 'CanExecuteChanged'を確実にするためのさまざまな戦略について議論しています。マークされた複製など。 https://stackoverflow.com/questions/7350845/canexecute-logic-for-delegatecommand、https://stackoverflow.com/questions/6425923/canexecutechanged-event-of-icommand、https://stackoverflow.com/も参照してください。質問/ 30002300/how-to-use-canexecute-method-icommand-on-wpfhttps:// stackoverflowを参照してください。com/questions/14479303/icommand-canexecute-not-triggered-after-propertychanged ... –
https://stackoverflow.com/questions/31078633/wpf-icommand-canexecute-raisecanexecutechanged-or-automatic-handling-via -di。あなたの質問は、既に書かれたすべてのものの再ハッシュか、まったく広範なStack Overflowの質問です。あなたの質問はあなたのウェブページへのリンクを投稿する単なる言い訳ではないと考えてみましょう。あなたが本当に助けたいと思う質問がある場合は、より具体的な新しい質問を投稿してください。これには良い[mcve]とあなたが解決しようとしている解決策の詳細な説明が含まれています。 –
@PeterDunihoあなたのための上記のコメント。 –