I am working on a Win10 UWP app using MVVMLight (I've never used MVVMLight, and never done commands "properly"). I have an ItemsControl bound to an ObservableCollection. The Participant has two properties - Name and Laps. I have controls in the ItemsControl.ItemTemplate to display a button (subtract), the Name property of the item, the Laps property of the item, and another button (add). Here is the XAML:
<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=""
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=""
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>
The view model creates an ObservableCollection called Participants. I am trying to bind the add button (and then of course the subtract button) to a RelayCommand in the VM. I've tried a number of things, so I can't post all I've tried here. Here is the latest of what I have, (but it still doesn't work):
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();
}
The intellisense in the xaml tells me that it cannot resolve the property AddLapCommand in data context of type LapCounter.Model.Participant. I'm not trying to get to the Participant class, but to the HomeViewModel class, which is the DataContext of the page. I think I can see where it is getting the LapCounter.Model.Participant from, from the individual item in the collection that the ItemsControl is bound to. But I was under the impression that if a DataContext couldn't be found, it would continue up the visual tree until it found the right one. Here's the DataContext in the page declaration:
DataContext="{Binding Home, Source={StaticResource Locator}}"
How do I get it to look at the VM for the RelayCommand? What I need to do is have the button send the Participant that it represents to the RelayCommand as a parameter, and use that to increment (and decrement in the case of the subtract button) the Laps integer for that particular Participant.
I appreciate any help I can get. Thanks!
EDIT Added Participants property from the VM to show because my view is not updating. Here is the Participants property:
/// <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);
}
}
Thanks to Eldar Dordzhiev for his help so far!