I have a XAML View and a View Model in my project. The project is a stopwatch and as a Lap button is pressed it adds an object to an ObservableCollection which is displayed in the view as a ListView.
In the ListView I have added a button to delete one of the Collection items. It has a Command with a Binding of "DeleteTimingCommand" and a CommandParameter with a Binding of "Position" which is the identifier I want to use in order to delete the object from the collection.
The DeleteTimingCommand is in the ViewModel constructor and set to fire a method called "DeleteTiming". This method then takes care of the actual deletion.
However, I can't get my code to hit my DeleteTiming() method at all! No matter where I put a breakpoint, nothing is firing it. I press the button and nothing happens.
Something isn't hooked up right. Can anyone point me in the right direction?
XAML
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TechsportiseApp.Views.Timer" Title="Timer">
<StackLayout VerticalOptions="Start" HorizontalOptions="FillAndExpand">
<StackLayout Orientation="Horizontal">
<Label Text="{Binding ElapsedTime}" HorizontalOptions="FillAndExpand" HorizontalTextAlignment="Center" FontSize="40"/>
<Button Command="{Binding LapCommand}" BackgroundColor="#eca400" IsVisible="{Binding EndVisibility}" Image="Scanning.png" WidthRequest="50" HeightRequest="50"/>
</StackLayout>
<Button x:Name="buttonStart" Text="Start Race" Command="{Binding StartTimerCommand}" IsVisible="{Binding StartVisibility}" />
<Button x:Name="buttonEnd" Text="End Race" Command="{Binding EndTimerCommand}" IsVisible="{Binding EndVisibility}" />
<Button x:Name="buttonSubmit" Text="Submit Results" Command="{Binding EndTimerCommand}" IsVisible="{Binding SubmitVisibility}" />
<BoxView HeightRequest="1" Color="Silver" HorizontalOptions="FillAndExpand" />
<Label Text="YOUR RESULTS" HorizontalOptions="FillAndExpand" HorizontalTextAlignment="Center" FontSize="Small" FontAttributes="Bold"/>
<BoxView HeightRequest="1" Color="Silver" HorizontalOptions="FillAndExpand" />
<ListView ItemsSource="{Binding Timings}"
SeparatorVisibility="None"
HasUnevenRows="true">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid RowSpacing="3" ColumnSpacing="3">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>
<Label x:Name="Pos" Text="{Binding Position}" VerticalTextAlignment="Center" HorizontalTextAlignment="Center" Grid.Row="0" Grid.Column="0" FontSize="Large" FontAttributes="Bold"/>
<Label Text="{Binding Elapsed}" VerticalTextAlignment="Center" Grid.Row="0" Grid.Column="1" FontSize="Large" />
<Button Image="trash.png" BackgroundColor="Red" WidthRequest="50" HeightRequest="50" Command="{Binding DeleteTimingCommand}" CommandParameter="{Binding Position}" Grid.Row="0" Grid.Column="2" />
<BoxView HeightRequest="1" Color="Silver" HorizontalOptions="FillAndExpand" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
ViewModel
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Timers;
using System.Windows.Input;
using TechsportiseApp.Models;
using Xamarin.Forms;
namespace TechsportiseApp.ViewModels
{
public class TimerViewModel : INotifyPropertyChanged
{
public Timer myTimer = new Timer();
public ICommand StartTimerCommand { get; set; }
public ICommand EndTimerCommand { get; set; }
public ICommand LapCommand { get; set; }
public ICommand DeleteTimingCommand { get; set; }
public TimerViewModel()
{
StartTimerCommand = new Command(StartTimer);
EndTimerCommand = new Command(EndTimer);
LapCommand = new Command(LapButton);
DeleteTimingCommand = new Command<int>(DeleteTiming);
Timings = new ObservableCollection<Timing>();
LapPosition = 1;
StartVisibility = true;
EndVisibility = false;
SubmitVisibility = false;
}
//TimeSpan _elapsedTime;
//public TimeSpan ElapsedTime
//{
// get {
// return _elapsedTime;
// }
// set
// {
// if (_elapsedTime == value)
// return;
// _elapsedTime = value;
// OnPropertyChanged("ElapsedTime");
// }
//}
string _elapsedTime;
public String ElapsedTime
{
get
{
if (_elapsedTime != null)
{
return _elapsedTime;
}
else
{
_elapsedTime = "00:00:00.00";
return _elapsedTime;
}
}
set
{
if (_elapsedTime == value)
return;
_elapsedTime = value;
OnPropertyChanged("ElapsedTime");
}
}
DateTime _currentTime;
public DateTime CurrentTime
{
get { return _currentTime; }
set
{
if (_currentTime == value)
return;
_currentTime = value;
OnPropertyChanged("CurrentTime");
}
}
bool _startVisibility;
public bool StartVisibility
{
get { return _startVisibility; }
set
{
if (_startVisibility == value)
return;
_startVisibility = value;
OnPropertyChanged("StartVisibility");
}
}
bool _endVisibility;
public bool EndVisibility
{
get { return _endVisibility; }
set
{
if (_endVisibility == value)
return;
_endVisibility = value;
OnPropertyChanged("EndVisibility");
}
}
bool _submitVisibility;
public bool SubmitVisibility
{
get { return _submitVisibility; }
set
{
if (_submitVisibility == value)
return;
_submitVisibility = value;
OnPropertyChanged("SubmitVisibility");
}
}
DateTime _raceStartTime;
public DateTime RaceStartTime
{
get { return _raceStartTime; }
set
{
if (_raceStartTime == value)
return;
_raceStartTime = value;
OnPropertyChanged("RaceStartTime");
}
}
DateTime _lapTime;
public DateTime LapTime
{
get { return _lapTime; }
set
{
if (_lapTime == value)
return;
_lapTime = value;
OnPropertyChanged("LapTime");
}
}
ObservableCollection<Timing> _timings;
public ObservableCollection<Timing> Timings
{
get
{
//var sortedtimings = new ObservableCollection<Timing>(_timings.OrderBy(c => c.Position));
var sortedtimings = new ObservableCollection<Timing>(_timings.OrderByDescending(c => c.Position));
_timings = sortedtimings;
return _timings;
}
set
{
if (_timings != value)
{
_timings = value;
OnPropertyChanged("Timings");
}
}
}
int _lapPosition;
public int LapPosition
{
get { return _lapPosition; }
set
{
if (_lapPosition == value)
return;
_lapPosition = value;
OnPropertyChanged("LapPosition");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
var changed = PropertyChanged;
if (changed != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
void StartTimer()
{
RaceStartTime = DateTime.Now;
myTimer.Elapsed += new ElapsedEventHandler(DisplayTimeEvent);
myTimer.Interval = 10; // 1000 ms is one second
myTimer.Start();
StartVisibility = false;
EndVisibility = true;
//ElapsedTime = myTimer.Elapsed.Milliseconds() += new ElapsedEventHandler(DisplayTimeEvent);
}
void EndTimer()
{
myTimer.Stop();
EndVisibility = false;
SubmitVisibility = true;
//ElapsedTime = myTimer.Elapsed.Milliseconds() += new ElapsedEventHandler(DisplayTimeEvent);
}
void DisplayTimeEvent(object source, ElapsedEventArgs e)
{
TimeSpan _elapsed;
_elapsed = e.SignalTime - RaceStartTime;
string hours = _elapsed.Hours.ToString().PadLeft(2, '0');
string minutes = _elapsed.Minutes.ToString().PadLeft(2, '0');
string seconds = _elapsed.Seconds.ToString().PadLeft(2, '0');
int _hundredths = _elapsed.Milliseconds / 10;
string hundredths = _hundredths.ToString().PadLeft(2, '0');
_elapsedTime = hours + ":" + minutes + ":" + seconds + "." + hundredths;
ElapsedTime = _elapsedTime;
OnPropertyChanged("ElapsedTime");
}
void LapButton()
{
var lap = new Timing
{
Id = 0,
RaceId = 0,
StartTime = RaceStartTime,
EndTime = DateTime.Now,
Elapsed = ElapsedTime,
Position = LapPosition,
Status = 0
};
Timings.Add(lap);
OnPropertyChanged("Timings");
LapPosition = LapPosition + 1;
var listcheck = Timings.Count;
}
void DeleteTiming(int position)
{
foreach (var timing in Timings)
{
if (timing.Position == position)
{
Timings.Remove(timing);
break;
}
}
var NewPosition = Timings.Count();
foreach (var timing in Timings)
{
timing.Position = NewPosition;
NewPosition = NewPosition - 1;
}
OnPropertyChanged("Timings");
}
}
}