2016-04-19 3 views
2

Я работаю над приложением Win10 UWP с использованием MVVMLight (я никогда не использовал MVVMLight и никогда не делал команды «правильно»). У меня есть элемент ItemsControl, связанный с ObservableCollection. У участника есть два свойства - имя и круги. У меня есть элементы управления ItemsControl.ItemTemplate, чтобы отобразить кнопку (вычесть), свойство Name элемента, свойство Laps элемента и другую кнопку (добавить). Вот XAML:Binding Command to ItemsControl Item

<ItemsControl 
        ItemsSource="{Binding Participants, Mode= TwoWay}"> 
        <ItemsControl.ItemTemplate> 
         <DataTemplate> 
          <Grid 
           MinWidth="300" 
           Margin="0, 12"> 
           <Grid.ColumnDefinitions> 
            <ColumnDefinition 
             Width="2*"></ColumnDefinition> 
            <ColumnDefinition 
             Width="6*"></ColumnDefinition> 
            <ColumnDefinition 
             Width="2*"></ColumnDefinition> 
            <ColumnDefinition 
             Width="3*"></ColumnDefinition> 
           </Grid.ColumnDefinitions> 
           <Button 
            Content="&#xE108;" 
            FontFamily="Segoe MDL2 Assets" 
            FontSize="20" 
            Grid.Column="0" 
            Margin="0, 0, 12, 0"></Button> 
           <TextBlock 
            Text="{Binding Path=Name, Mode=TwoWay}" 
            FontSize="20" 
            FontWeight="Bold" 
            Grid.Column="1"></TextBlock> 
           <TextBlock 
            Text="{Binding Laps, Mode=TwoWay}" 
            FontSize="20" 
            FontWeight="Bold" 
            Grid.Column="2"></TextBlock> 
           <Button 
            Content="&#xE710;" 
            FontFamily="Segoe MDL2 Assets" 
            FontSize="20" 
            Command="{Binding AddLapCommand}" 
            CommandParameter="{Binding}" 
            Grid.Column="3" 
            Margin="12, 0, 0, 0"></Button> 
          </Grid> 
         </DataTemplate> 
        </ItemsControl.ItemTemplate> 
       </ItemsControl> 

Модель вида создает ObservableCollection, называемый Участники. Я пытаюсь связать кнопку добавления (а затем, конечно, кнопку вычитания) с RelayCommand в виртуальной машине. Я пробовал несколько вещей, поэтому я не могу опубликовать все, что я пробовал здесь. Вот последняя из того, что у меня есть, (но она по-прежнему не работает):

public RelayCommand<object> AddLapCommand 
    { 
     get 
     { 
      if (_addLapCommand == null) 
      { 
       _addLapCommand = new RelayCommand<object>((e) => ExecuteAddLapCommand(e)); 
      } 
      return _addLapCommand; 
     } 
    } 

    private void ExecuteAddLapCommand(object o) 
    { 
     throw new NotImplementedException(); 
    } 

IntelliSense в XAML говорит мне, что он не может разрешить AddLapCommand собственности в контексте данных типа LapCounter.Model.Participant , Я не пытаюсь перейти к классу участника, но к классу HomeViewModel, который является DataContext страницы. Я думаю, я могу видеть, откуда он получает LapCounter.Model.Participant от, из отдельного элемента в коллекции, к которому привязан ItemControl. Но у меня создалось впечатление, что если DataContext не может быть найден, он продолжит визуальное дерево, пока не найдет правильный. Вот DataContext в объявлении страницы:

DataContext="{Binding Home, Source={StaticResource Locator}}" 

Как заставить его смотреть на VM для RelayCommand? Мне нужно сделать, чтобы кнопка отправила Участнику, который он представляет в RelayCommand в качестве параметра, и использует это для увеличения (и уменьшения в случае кнопки вычитания) целого числа Laps для этого конкретного Участника.

Я ценю любую помощь, которую я могу получить. Благодаря!

EDIT Добавлено свойство Участников из виртуальной машины, чтобы показать, потому что мое представление не обновляется. Вот свойство Участников:

/// <summary> 
    /// The <see cref="Participants" /> property's name. 
    /// </summary> 
    public const string ParticipantsPropertyName = "Participants"; 

    private ObservableCollection<Participant> _participants = new ObservableCollection<Participant>(); 

    /// <summary> 
    /// Sets and gets the Participants property. 
    /// Changes to that property's value raise the PropertyChanged event. 
    /// </summary> 
    public ObservableCollection<Participant> Participants 
    { 
     get 
     { 
      return _participants; 
     } 

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

      _participants = value; 
      RaisePropertyChanged(() => Participants); 
     } 
    } 

Благодаря Эльдару Дорджиеву за помощь!

ответ

1

Попробуйте это:

Command="{Binding Home.AddLapCommand, Source={StaticResource Locator}}" 

Там не так много, чтобы объяснить вам, пока все, что вы написали, абсолютно правильно.

Что касается увеличения/уменьшения Laps, вы можете просто передать Participant в обработчик команд и изменить Laps. Если вы используете MVVMLight, это делается с помощью RelayCommand<Participant>. Не забудьте передать Participant в CommandParameter.

+0

Спасибо, Эльдар. Это решило эту проблему. Теперь моя RelayCommand работает, и свойство Laps Участника обновляется. Теперь проблема в том, что отображение Laps в представлении не обновляется. Я добавил код из VM свойства участников, и он реализует RaisePropertyChanged, но он не работает. Не собирается ли коллекция RaisePropertyChanged, если элемент в коллекции изменен? –

+0

Ничего - я понял это благодаря этому сообщению (http://stackoverflow.com/questions/5285377/wpf-mvvm-inotifypropertychanged-implementation-model-or-viewmodel). Он работает сейчас. Спасибо! –

+0

@RichHopkins Вам нужно реализовать 'INotifyPropertyChanged' в классе' Участник '. Пожалуйста, не забудьте отметить мой ответ в качестве ответа, если он вам поможет. –