开发者

Accessing ICommands from MainWindow : Josh Smith's Article

I am following Josh Smith's Design explaining WPF + MVVM. I almost have the same requirement 开发者_如何学运维as his demo application. I have to assign the Save command from his CustomerViewModel class to a Toolbar button in the Main Window.

Is it possible to do through XAML or only through code-behind and how?

thanks


You can do this:

<Menu Height="23" HorizontalAlignment="Left" Name="menu1" VerticalAlignment="Top" Width="289" >
    <MenuItem Header="File">
        <MenuItem Header="Save" Command="Save"/>
    </MenuItem>
</Menu>

I am pretty sure this calls the default save method, but if you want to define a custom save method you could do:

<Menu Height="23" HorizontalAlignment="Left" Name="menu1" VerticalAlignment="Top" Width="289" >
    <MenuItem Header="File">
        <MenuItem Header="Save" Command="{Binding Path="CustomSaveCommand"}"/>
    </MenuItem>
</Menu>

Make sure you add a datacontext reference to your viewmodel like this

<Window.DataContext>
    <my:MainWindowViewModel/>
</Window.DataContext>


Thanks for your reply, Paul. Here's what I ended up doing. As I mentioned above, I was using Josh Smith's design, I wanted to call the Save() method (Command) of CustomerViewModel object from the MainWindowViewModel. So from the Main window I attached a click event to my Toolbar Button like this.

<Button Name="btnSaveAllWorkspaces" ToolTip="Save All Open Workspaces" Content="Save All" Click="OnSaveAllWorkspacesClicked"/>        

And then in code behind,

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();
                }
            }
        }
    }

Initially I just wanted to save the currently active Workspace only, but then I thought as it is a Global Button on top of all the Workspaces, it makes sense to save all the open workspaces, hence the foreach loop.

Please free feel to share if there is a better way to do this just through XAML?

thanks


I knew whatever I had done earlier was a workaround and it was dirty. As I understood more about MVVM, I kept re-factoring the code. Here's what I did.

Added the ICommand Proerty for SaveCommand on MainWindowViewModel, and bound it to the toolbutton on Main Window. It just delegates the call to the currently active WorksSpaceViewModel's SaveCommand.

   public override ICommand SaveCommand
    {
        get
        {
            return _currentWorkspace != null ? _currentWorkspace.SaveCommand : new RelayCommand ( null, param => false);
        }
    }

and as in the original code, where it keeps track of current workspace, made sure I notified the subsystem of the change

    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");
        }
    }

that's it, WPF took care of the rest (ie, enabling, disabling button depending on the validations)!

Again, thanks for your tip Paul.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜