2016-04-12 3 views
0

Это еще один вопрос к моей другой теме: MVVM Navigating through different Views, я выяснил, что проблема пока не решена (другая тема). Этот вопрос связан с Predicate моей команды (метод CanExecute).Предикат не будет правильно проверять параметр

public RelayCommand ChangePageCommand { 
     get { 
      return new RelayCommand(p => ChangeViewModel((BaseViewModel)p), x => x is BaseViewModel); 
     } 
    } 

    public RelayCommand TestChangePageCommand { 
     get { 
      return new RelayCommand(p => MessageBox.Show((p is BaseViewModel).ToString()), x => true); 
     } 
    } 

Я создал какой-то метод испытания, чтобы определить, где актуальна проблема находится:

MessageBox.Show((p is BaseViewModel).ToString()) 

из TestChangePageCommand показывает DialogBox с «истинным», но предиката от ChangePageCommand

x => x is BaseViewModel 

всегда возвращает «false» (также предикат из TestChangePageCommand делает, если он реализован)

Может кто-нибудь может понять, почему мое приложение ведет себя так?

Update 1:

Выход из окна говорит:

Не удается получить значение с помощью связывания и не действует резервное значение не существует; используя вместо этого по умолчанию. BindingExpression: Path = HomePage; DataItem = NULL; целевым элементом является «Button» (Name = ''); предназначаться свойство является «CommandParameter» (тип «Объект»)

Update 2:

Я проверил ViewModel и выяснили, что HomePage не является нулевым, когда он получить Установим как CurrentPageViewModel. Возможно ли, что метод CanExecute будет выполняться при создании ViewModel и HomePage еще не определен? Как я могу это решить?

UserAdministrationViewModel which contains the HomeViewModel (as HomePage)

+1

Поместите точку останова на 'x => x is BaseViewModel' и сообщите нам, что такое' x'. Кроме того, не записывайте свойства только для чтения, как и вы, - ваш геттер снова и снова создает новые экземпляры RelayCommand. Создайте команду один раз и кешируйте значение в закрытом поле. – Dennis

+0

вы можете протестировать запуск сообщения из canececute, выполнив x.ToString(); знать, что на самом деле происходит x, или он даже называется – Nitin

+0

. Как-то x имеет значение null, когда выполняется метод CanExecute, но, как уже упоминалось, если я модифицирую метод CanExecute, чтобы просто вернуть true, и нажмите кнопку, он вернет «HomeViewModel» », который происходит из BaseViewModel. После изменения некоторых параметров окна вывода говорят, что свойство «HomePage» не найдено для «объекта», потому что элемент данных имеет значение NULL. Это может произойти, потому что поставщик данных еще не выдал никаких данных ». – C4p741nZ

ответ

1

Как уже упоминалось выше, Dennis в комментарии, вы должны попытаться Cashe вашу команду. Отвод попробовать следующую вещь, поставить точку останова на предикат линии, и посмотреть, что вы получите:

ICommand _command; 
    public RelayCommand ChangePageCommand 
    { 
     get 
     { 
      return _command ?? (_command = new RelayCommand(p => ChangeViewModel((BaseViewModel) p), x => 
      { 
       x is BaseViewModel; 
      })); 
     } 
    } 

Попробуйте изменить следующий метод:

public void ChangeViewModel(BaseViewModel viewModel) 
    { 
     //You should implement clone in your base view model 
     CurrentPageViewModel = viewModel.Clone(); 
    } 

Update # 2 - Вот ваш код

<Button Content="{Binding Name}" Command="{Binding DataContext.ChangePageCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" 
      CommandParameter="{Binding HomePage}"/> 

Я думаю, вы должны добавить UpdateSourseTrigger = PropertyChanged к вашему определению Кнопка CommandParameter. Поскольку я понимаю, что HomePage может быть нулевым только во времени, когда нет какого-либо предка типа окна. Это произойдет только при перемещении между двумя DataTemplates (в вашем случае). Попытайтесь думать в этом подходе.

С уважением,

+0

Приятно знать, спасибо! Но, как упоминалось, как-то x имеет значение null, когда в Predicate и Type HomeViewModel при нажатии на кнопку (если я изменяю Predicate, чтобы просто вернуть true) – C4p741nZ

+0

@ Chill-X вы написали команду? Вы работаете в async? – Ilan

+0

Да, я кэшировал команду - по-прежнему та же проблема. Я не понимаю, почему HomePage «null», когда вызывается CanExecute, но из типа HomeViewModel, когда вызывается вызов Execute get ... – C4p741nZ

0

В конце дает мой UserControl имя и перенаправить CommandProperty вдоль ElementName сделал трюк:

<Button Content="{Binding Name}" Command="{Binding DataContext.ChangePageCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" 
     CommandParameter="{Binding DataContext.HomePage, ElementName=Test}"/> 

Может кто-нибудь объяснить, почему Binding на имя (которое находится в тот же базовый класс) работает без ElementName/предоставления дополнительной информации, но HomePage не работает?