RelayCommand не запускает CanExecute - PullRequest
0 голосов
/ 18 февраля 2012

Я пытаюсь создать команду, которая привязывается к кнопке и зависит от иерархии моделей представления для представления сводной точки и сводных элементов в приложении wp7.Это выглядит примерно так (я опущу как можно больше стандартного кода):

Родительская модель представления:

    public RelayCommand RefreshCommand
    {
        get
        {
            return _refreshCommand;
        }

        set
        {
            if (_refreshCommand == value)
            {
                return;
            }

            var oldValue = _refreshCommand;
            _refreshCommand = value;

            // Update bindings, no broadcast
            RaisePropertyChanged(RefreshCommandPropertyName);
        }
    }


    public RelayCommand<RoutedEventArgs> LoadedCommand
    {
        get
        {
            Action<RoutedEventArgs> getCurrentViewmodel = (args) =>
            {
                CurrentViewModel = SearchByLocationViewModel; // maybe something better...
                RefreshCommand = CurrentViewModel.RefreshResultsCommand;
                RefreshCommand.RaiseCanExecuteChanged();
            };
            return new RelayCommand<RoutedEventArgs>(getCurrentViewmodel);
        }
    }

    public RelayCommand<SelectionChangedEventArgs> PivotItemChangedCommand
    {
        get
        {
            Action<SelectionChangedEventArgs> pivotChanged = (args) =>
            {
                if (args != null)
                {
                    // update current viewmodel
                    CurrentViewModel = ((Microsoft.Phone.Controls.PivotItem) args.AddedItems[0]).DataContext as ISearchViewModelBase;
                    RefreshCommand = CurrentViewModel.RefreshResultsCommand;
                }
            };
            return new RelayCommand<SelectionChangedEventArgs>(pivotChanged);
        }
    }

Итак, я устанавливаю свойство RefreshCommand модели родительского представления в значениедочерняя команда каждый раз, когда она загружается, и я делаю то же самое, когда изменяется выбранный сводный элемент.

Xaml

<Button Command="{Binding RefreshCommand}" />

дочерняя модель представления

public Func<bool> CanRefresh
{
    get { return () => !IsLoading; }
}

private RelayCommand refreshResultsCommand;

public RelayCommand RefreshResultsCommand
{
    get
    {
        Action doRefresh = () =>
        {
            SearchResults.Clear();
            this._pageNumber = 0;
            AddItems();
        };
        return refreshResultsCommand = refreshResultsCommand ?? new RelayCommand(doRefresh, CanRefresh);
    }
}

Что происходит,CanRefresh НИКОГДА не вызывается.Команды работают нормально, в зависимости от того, какой стержень он вызывает один AddItems (это виртуальный метод, реализованный по-разному в каждой дочерней модели представления) или другой, но это похоже на то, что CanExecute никогда не вызывается.Я использую инструментарий MVVM Light.Спасибо!

Ответы [ 2 ]

1 голос
/ 18 февраля 2012

Я подозреваю, что метод CanExecute никогда не вызывается, потому что событие CanExecuteChanged RelayCommand никогда не вызывается для объекта модели представления, с которым в данный момент связан слой представления.Поскольку вы создаете команды для большинства обращений к свойствам, существует множество команд, и вполне возможно, что вы запускаете событие для команды, которая еще не связана с уровнем представления, или той, которая не имеетбольше привязан к.

Я никогда не видел, чтобы кто-нибудь создавал новые команды каждый раз, когда вызывается свойство getter.Не могли бы вы попробовать создать команды один раз в конструкторе, а не при каждом доступе к свойству, и посмотреть, исправит ли это что-то?

0 голосов
/ 18 февраля 2012

Итак, вы создаете новую команду relay каждый раз, когда вызываете ваши свойства LoadedCommand и PivotChangedComman. Так как SL / WPF вызывает эти свойства довольно часто, вы должны убедиться, что вы не создаете команду каждый раз, когда вызывается свойство. На самом деле ваш RefreshResultsCommand реализует правильный шаблон.

Лучший способ убедиться, что вы правильно реализуете свойства / команды, - это использовать фрагменты Laurent MVVM . Загрузите их в свой каталог сниппетов и просто используйте их. Помимо того, что они производят всегда один и тот же стандартный код и, следовательно, улучшают качество, они также значительно ускоряют процесс!

Вы можете использовать программу установки , чтобы также установить фрагменты.

...