私はWPF + MVVM を説明する Josh Smith の Designに従っています。彼のデモアプリケーションとほぼ同じ要件があります。彼の CustomerViewModel クラスの Save コマンドをメイン ウィンドウのツールバー ボタンに割り当てる必要があります。
XAML を介して行うことは可能ですか、またはコード ビハインドのみを介して行うことができますか?
ありがとう
私はWPF + MVVM を説明する Josh Smith の Designに従っています。彼のデモアプリケーションとほぼ同じ要件があります。彼の CustomerViewModel クラスの Save コマンドをメイン ウィンドウのツールバー ボタンに割り当てる必要があります。
XAML を介して行うことは可能ですか、またはコード ビハインドのみを介して行うことができますか?
ありがとう
あなたはこれを行うことができます:
<Menu Height="23" HorizontalAlignment="Left" Name="menu1" VerticalAlignment="Top" Width="289" >
<MenuItem Header="File">
<MenuItem Header="Save" Command="Save"/>
</MenuItem>
</Menu>
これはデフォルトの保存メソッドを呼び出すと確信していますが、カスタムの保存メソッドを定義したい場合は、次のようにすることができます。
<Menu Height="23" HorizontalAlignment="Left" Name="menu1" VerticalAlignment="Top" Width="289" >
<MenuItem Header="File">
<MenuItem Header="Save" Command="{Binding Path="CustomSaveCommand"}"/>
</MenuItem>
</Menu>
このようにビューモデルにデータコンテキスト参照を追加してください
<Window.DataContext>
<my:MainWindowViewModel/>
</Window.DataContext>
お返事ありがとうございます、ポール。これが私がやったことです。上で述べたように、私は Josh Smith のデザインを使用していましたが、MainWindowViewModel からオブジェクトのSave()
メソッド (Command)を呼び出したいと考えていました。CustomerViewModel
メイン ウィンドウから、このようにツールバー ボタンにクリック イベントを追加しました。
<Button Name="btnSaveAllWorkspaces" ToolTip="Save All Open Workspaces" Content="Save All" Click="OnSaveAllWorkspacesClicked"/>
そして、コードビハインドで、
private void OnSaveAllWorkspacesClicked(object sender, RoutedEventArgs e)
{
if (MainVM != null)
{
if (MainVM.Workspaces != null && MainVM.Workspaces.Count > 0)
{
foreach (WorkspaceViewModel wkVM in MainVM.Workspaces)
{
CustomerViewModel vm = wkVM as CustomerViewModel;
if (vm != null)
vm.Save();
}
}
}
}
最初は、現在アクティブなワークスペースのみを保存したかっただけでしたが、それはすべてのワークスペースの上にあるグローバル ボタンであるため、開いているすべてのワークスペースを保存するのが理にかなっており、foreach
ループが発生しています。
XAML だけでこれを行うためのより良い方法がある場合は、お気軽に共有してください。
ありがとう
以前に行ったことは回避策であり、汚れていることはわかっていました。MVVM について理解を深めるにつれて、コードのリファクタリングを続けました。これが私がしたことです。
MainWindowViewModel の SaveCommand に ICommand プロパティを追加し、メイン ウィンドウのツールボタンにバインドしました。現在アクティブな WorksSpaceViewModel の SaveCommand への呼び出しを委任するだけです。
public override ICommand SaveCommand
{
get
{
return _currentWorkspace != null ? _currentWorkspace.SaveCommand : new RelayCommand ( null, param => false);
}
}
そして、元のコードのように、現在のワークスペースを追跡し、サブシステムに変更を通知したことを確認しました
public ObservableCollection<WorkspaceViewModel> Workspaces
{
get
{
if (_workspaces == null)
{
_workspaces = new ObservableCollection<WorkspaceViewModel>();
_workspaces.CollectionChanged += OnWorkspacesChanged;
CollectionViewSource.GetDefaultView(_workspaces).CurrentChanged += new EventHandler(MainWindowViewModel_CurrentChanged);
}
return _workspaces;
}
}
private void MainWindowViewModel_CurrentChanged(object sender, EventArgs e)
{
CurrentWorkspace = CollectionViewSource.GetDefaultView(_workspaces).CurrentItem as WorkspaceViewModel;
OnPropertyChanged("SaveCommand");
}
public WorkspaceViewModel CurrentWorkspace
{
get { return _currentWorkspace; }
set
{
_currentWorkspace = value;
OnPropertyChanged("CurrentWorkspace");
}
}
それだけです。WPF が残りの処理を行います (つまり、検証に応じてボタンの有効化、無効化)。
繰り返しますが、ポールのヒントに感謝します。