MVVMを使用してリボンでCanExecuteを呼び出す方法 各タブ項目でタブコントロールと編集コントロールを持つシンプルなアプリがあります。これはViewModelにリンクされており、コマンド(ルーティングされていないもの)も定義されています。メニューで使用されます。これまでにすべてがうまくいきました。MVVMを使用してリボンでCanExecuteを強制呼び出しする方法
ここでは、いくつかの条件(たとえば、[保存]または[ワードラップ]は、タブ項目がアクティブになっている場合のみ有効になります)で有効になっているボタン付きのリボンを使用します。残念ながら、すべてのコマンドのCanExecuteメソッドは、アプリケーションのロード中に一度だけ呼び出されます。 ViewModelの何かが変更されたときにそれを確認する方法を教えてください。
詳細(WPF 4.6.1):
RelayCommand:ワードラップのため
public class RelayCommand : ICommand
{
private Action _execute;
private Func<bool> _canExecute;
public RelayCommand(Action execute, Func<bool> canExecute)
{
_execute = execute;
_canExecute = canExecute;
}
public void RaiseCanExecuteChanged()
{
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
public bool CanExecute(object parameter)
{
if (_canExecute != null)
return _canExecute();
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
_execute();
}
}
コマンド:
private RelayCommand _ChangeWordWrapCommand;
public RelayCommand ChangeWordWrapCommand
{
get
{
if (_ChangeWordWrapCommand == null)
_ChangeWordWrapCommand = new RelayCommand(
() => { ((TextDocument)ActiveDocument).WordWrap = !((TextDocument)ActiveDocument).WordWrap; },
() => { return (ActiveDocument != null); }
);
return _ChangeWordWrapCommand;
}
}
のActiveDocumentとオープンドキュメントのプロパティ:
public ObservableCollection<Document> OpenedDocuments { get; private set; }
private Document _ActiveDocument;
public Document ActiveDocument
{
get { return _ActiveDocument; }
set
{
_ActiveDocument = value;
OnPropertyChanged(nameof (ActiveDocument));
}
}
N ewFileコマンド実行:
private Document NewFile()
{
TextDocument result = new TextDocument(new Model.TextDocument());
result.FileName = $"Untitled {UntitledFileNumber++}";
OpenedDocuments.Add(result);
ActiveDocument = result;
return result;
}
リボンの定義(一部だけ):ワードラップが無効になっているので、最初に
<Ribbon x:Name="Ribbon" SelectedIndex="0" UseLayoutRounding="False">
<RibbonTab Header="Home" KeyTip="H" >
<RibbonGroup x:Name="Files" Header="Files" >
<RibbonButton Label="New" KeyTip="N" Command="{Binding Path=NewFileCommand, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
<RibbonButton Label="WordWrap" KeyTip="W" Command="{Binding Path=ChangeWordWrapCommand, Mode=OneWay, UpdateSourceTrigger=Default}" />
</RibbonGroup>
</RibbonTab>
</Ribbon>
は、何のファイルが、そこ開かれません。リボンのボタンも同様です。 NewFileCommandを実行すると、コントロールで新しいタブが作成されますが、WordWrapコマンドは無効のままです。
私は、勧告はのActiveDocumentセッターでRaiseCanExecuteChangedを呼び出すことで、この記事を見つけたWPF MVVM command canexecute enable/disable button:
public Document ActiveDocument
{
get { return _ActiveDocument; }
set
{
_ActiveDocument = value;
OnPropertyChanged(nameof(ActiveDocument));
ChangeWordWrapCommand.RaiseCanExecuteChanged();///really
}
}
これは動作しますが、それは私には非常に奇妙に聞こえます。なぜプロパティは、それを使用するすべてのコマンドを知っている必要があり、それらを世話する必要がありますか?この問題の解決策はありますか?
CommandManager.RequerySuggested? – Aybe