Доступ к ICommands из MainWindow: статья Джоша Смита - PullRequest
2 голосов
/ 02 августа 2011

Я следую Дизайн Джоша Смита, объясняющий WPF + MVVM .У меня почти такое же требование, как и у его демонстрационного приложения.Я должен назначить команду Сохранить из его класса CustomerViewModel для кнопки панели инструментов в главном окне.

Возможно ли это сделать через XAML или только через code-behind и как?

спасибо

Ответы [ 3 ]

3 голосов
/ 02 августа 2011

Вы можете сделать это:

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

Я почти уверен, что это вызывает метод сохранения по умолчанию, но если вы хотите определить собственный метод сохранения, вы можете сделать:* Убедитесь, что вы добавили ссылку на datacontext в вашу модель представления следующим образом

<Window.DataContext>
    <my:MainWindowViewModel/>
</Window.DataContext>
0 голосов
/ 02 февраля 2012

Я знал, что все, что я делал раньше, было обходным путем, и это было грязно. Как я понял больше о MVVM, я продолжал перефакторинг кода. Вот что я сделал.

Добавлено свойство ICommand для SaveCommand в MainWindowViewModel и привязано к кнопке инструментов в главном окне. Он просто делегирует вызов SaveCommand текущего активного WorksSpaceViewModel.

   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 позаботился обо всем остальном (т.е. включил, отключив кнопку в зависимости от проверок)!

Опять же, спасибо за ваш совет, Пол.

0 голосов
/ 02 августа 2011

Спасибо за ваш ответ, Пол. Вот что я в итоге сделал. Как я упоминал выше, я использовал дизайн Джоша Смита, я хотел вызвать метод Save() (Command) объекта CustomerViewModel из MainWindowViewModel. Поэтому в главном окне я прикрепил событие click к кнопке панели инструментов следующим образом.

<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?

спасибо

...