我遇到了Xamarin.Forms的问题,因为View并没有像我期望的那样令人耳目一新。
我已将View绑定到ViewModel,并且我有一系列方法来执行各种功能。
成功完成一项功能后,我希望它能够执行我的LoadResults()
方法。
最初加载视图时LoadResults()
方法正常工作。但是,当我执行任何其他方法(下面显示的DeleteScan(id)
方法)时,它应该重新激活LoadResults()方法并重新加载页面。
我知道它正在进入LoadResults()
方法,因为我已经在那里设置了一个断点并逐步完成了它。但到最后,它不会重新加载视图。
我也知道视图可以刷新,因为我有其他简单的方法只是更新VM中的属性,这些更改反映在UI中。
因此无论出于何种原因,LoadResults()
都没有重新加载页面。
我在这里做错了什么想法?
查看模型构造函数和属性
public class ResultsProcessViewModel : INotifyPropertyChanged
{
public ICommand AddTimingCommand { get; set; }
public ICommand AddScanCommand { get; set; }
public ICommand InsertTimingCommand { get; set; }
public ICommand InsertScanCommand { get; set; }
public ICommand DeleteTimingCommand { get; set; }
public ICommand DeleteScanCommand { get; set; }
public ICommand PublishCommand { get; set; }
public ICommand LoadResultsCommand { get; set; }
public ICommand CancelMissingFinisherCommand { get; set; }
public ICommand CancelMissingTimingCommand { get; set; }
public int RaceId { get; set; }
public DateTime RaceDate { get; set; }
//public ResultsViewModel(Race race)
public ResultsProcessViewModel(Race race)
{
AddTimingCommand = new Command<string>(AddTiming);
InsertTimingCommand = new Command(InsertTiming);
AddScanCommand = new Command<string>(AddScan);
InsertScanCommand = new Command(InsertScan);
DeleteTimingCommand = new Command<int>(DeleteTiming);
DeleteScanCommand = new Command<int>(DeleteScan);
PublishCommand = new Command(Publish);
LoadResultsCommand = new Command<int>(LoadResults);
CancelMissingFinisherCommand = new Command(CancelMissingFinisher);
CancelMissingTimingCommand = new Command(CancelMissingTiming);
Invalid = false;
PublishStatus = race.ResultStatus;
Published = false;
PublishVisibility = false;
AddTimingVisibility = false;
AddScanVisibility = false;
AddVisibility = true;
IsBusy = false;
RaceId = race.Id;
RaceDate = race.RaceDate;
RaceStartTime = Convert.ToDateTime(race.RaceStartTime);
Scans = ScansAPI.GetScans(RaceId);
Timings = TimingsAPI.GetTimings(RaceId);
Entries = EntriesAPI.GetEntries(RaceId);
LoadResults(RaceId);
}
ObservableCollection<GroupedResultModel> _grouped;
public ObservableCollection<GroupedResultModel> grouped
{
get { return _grouped; }
set
{
if (_grouped == value)
return;
_grouped = value;
OnPropertyChanged("Grouped");
}
}
DateTime _raceStartTime;
public DateTime RaceStartTime
{
get { return _raceStartTime; }
set
{
if (_raceStartTime == value)
return;
_raceStartTime = value;
OnPropertyChanged("RaceStartTime");
}
}
int _timingPosition;
public int TimingPosition
{
get { return _timingPosition; }
set
{
if (_timingPosition == value)
return;
_timingPosition = value;
OnPropertyChanged("TimingPosition");
}
}
int _addScanTimingId;
public int AddScanTimingId
{
get { return _addScanTimingId; }
set
{
if (_addScanTimingId == value)
return;
_addScanTimingId = value;
OnPropertyChanged("AddScanTimingId");
}
}
int _addTimingScanId;
public int AddTimingScanId
{
get { return _addTimingScanId; }
set
{
if (_addTimingScanId == value)
return;
_addTimingScanId = value;
OnPropertyChanged("AddTimingScanId");
}
}
int _scanPosition;
public int ScanPosition
{
get { return _scanPosition; }
set
{
if (_scanPosition == value)
return;
_scanPosition = value;
OnPropertyChanged("ScanPosition");
}
}
bool _isBusy;
public bool IsBusy
{
get { return _isBusy; }
set
{
if (_isBusy == value)
return;
_isBusy = value;
OnPropertyChanged("IsBusy");
}
}
bool _published;
public bool Published
{
get { return _published; }
set
{
if (_published == value)
return;
_published = value;
OnPropertyChanged("Published");
}
}
bool _publishVisibility;
public bool PublishVisibility
{
get { return _publishVisibility; }
set
{
if (_publishVisibility == value)
return;
_publishVisibility = value;
OnPropertyChanged("PublishVisibility");
}
}
bool _error;
public bool Error
{
get { return _error; }
set
{
if (_error == value)
return;
_error = value;
OnPropertyChanged("Error");
}
}
bool _addVisibility;
public bool AddVisibility
{
get { return _addVisibility; }
set
{
if (_addVisibility == value)
return;
_addVisibility = value;
OnPropertyChanged("AddVisibility");
}
}
bool _addTimingVisibility;
public bool AddTimingVisibility
{
get { return _addTimingVisibility; }
set
{
if (_addTimingVisibility == value)
return;
_addTimingVisibility = value;
OnPropertyChanged("AddTimingVisibility");
}
}
bool _addScanVisibility;
public bool AddScanVisibility
{
get { return _addScanVisibility; }
set
{
if (_addScanVisibility == value)
return;
_addScanVisibility = value;
OnPropertyChanged("AddScanVisibility");
}
}
ObservableCollection<Result> _results;
public ObservableCollection<Result> Results
{
get
{
return _results;
}
set
{
if (_results != value)
{
_results = value;
OnPropertyChanged("Results");
}
}
}
ObservableCollection<Scan> _scans;
public ObservableCollection<Scan> Scans
{
get
{
return _scans;
}
set
{
if (_scans != value)
{
_scans = value;
OnPropertyChanged("Scans");
}
}
}
ObservableCollection<Timing> _timings;
public ObservableCollection<Timing> Timings
{
get
{
return _timings;
}
set
{
if (_timings != value)
{
_timings = value;
OnPropertyChanged("Timings");
}
}
}
ObservableCollection<RaceEntry> _entries;
public ObservableCollection<RaceEntry> Entries
{
get
{
return _entries;
}
set
{
if (_entries != value)
{
_entries = value;
OnPropertyChanged("Entries");
}
}
}
bool _invalid;
public bool Invalid
{
get { return _invalid; }
set
{
if (_invalid == value)
return;
_invalid = value;
OnPropertyChanged("Invalid");
}
}
bool _resultsInvalid;
public bool ResultsInvalid
{
get { return _resultsInvalid; }
set
{
if (_resultsInvalid == value)
return;
_resultsInvalid = value;
OnPropertyChanged("ResultsInvalid");
}
}
bool _insertScanVisibility;
public bool InsertScanVisibility
{
get { return _insertScanVisibility; }
set
{
if (_insertScanVisibility == value)
return;
_insertScanVisibility = value;
OnPropertyChanged("InsertScanVisibility");
}
}
string _validationError;
public string ValidationError
{
get { return _validationError; }
set
{
if (_validationError == value)
return;
_validationError = value;
OnPropertyChanged("ValidationError");
}
}
string _resultsValidationError;
public string ResultsValidationError
{
get { return _resultsValidationError; }
set
{
if (_resultsValidationError == value)
return;
_resultsValidationError = value;
OnPropertyChanged("ResultsValidationError");
}
}
string _missingBib;
public string MissingBib
{
get { return _missingBib; }
set
{
if (_missingBib == value)
return;
_missingBib = value;
OnPropertyChanged("MissingBib");
}
}
string _errorMessage;
public string ErrorMessage
{
get { return _errorMessage; }
set
{
if (_errorMessage == value)
return;
_errorMessage = value;
OnPropertyChanged("ErrorMessage");
}
}
public Race SelectedRace { get; set; }
private bool _raceCountZero;
public bool RaceCountZero
{
get { return _raceCountZero; }
set
{
if (_raceCountZero == value)
return;
_raceCountZero = value;
OnPropertyChanged("RaceCountZero");
}
}
string _aboveBelow;
public string AboveBelow
{
get { return _aboveBelow; }
set
{
if (_aboveBelow == value)
return;
_aboveBelow = value;
OnPropertyChanged("AboveBelow");
}
}
string _aboveBelowPosition;
public string AboveBelowPosition
{
get { return _aboveBelowPosition; }
set
{
if (_aboveBelowPosition == value)
return;
_aboveBelowPosition = value;
OnPropertyChanged("AboveBelowPosition");
}
}
string _publishStatus;
public string PublishStatus
{
get { return _publishStatus; }
set
{
if (_publishStatus == value)
return;
_publishStatus = value;
OnPropertyChanged("PublishStatus");
}
}
string _newBatchCode;
public string NewBatchCode
{
get { return _newBatchCode; }
set
{
if (_newBatchCode == value)
return;
_newBatchCode = value;
OnPropertyChanged("NewBatchCode");
}
}
string _addHH;
public string AddHH
{
get { return _addHH; }
set
{
if (_addHH == value)
return;
_addHH = value;
OnPropertyChanged("AddHH");
}
}
string _addMM;
public string AddMM
{
get { return _addMM; }
set
{
if (_addMM == value)
return;
_addMM = value;
OnPropertyChanged("AddMM");
}
}
string _addSS;
public string AddSS
{
get { return _addSS; }
set
{
if (_addSS == value)
return;
_addSS = value;
OnPropertyChanged("AddSS");
}
}
string _scanBatchCode;
public string ScanBatchCode
{
get { return _scanBatchCode; }
set
{
if (_scanBatchCode == value)
return;
_scanBatchCode = value;
OnPropertyChanged("ScanBatchCode");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
var changed = PropertyChanged;
if (changed != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
DeleteScan方法
void DeleteScan(int scanid)
{
//Do stuff when deleting a scan. It needs to do all this in the observable collection. Then when we submit, we'll update all scans, timings etc with whats in the collection
Task.Run(() =>
{
try
{
Device.BeginInvokeOnMainThread(() => IsBusy = true);
var IsThereConnection = GlobalFunctions.CheckForInternetConnection();
if (IsThereConnection == false)
throw new Exception("You cannot delete a scan whilst you are offline");
//We are good to go
else
{
var deletescan = ScansAPI.DeleteScan(scanid);
if (deletescan.Code != "NoContent")
throw new Exception("Error deleting scan");
}
}
catch (Exception ex)
{
Device.BeginInvokeOnMainThread(() =>
{
ValidationError = ex.Message;
Invalid = true;
});
return;
}
finally
{
var newscans = ScansAPI.GetScans(RaceId);
var sortednewscans = new ObservableCollection<Scan>(newscans.OrderBy(c => c.Position));
Scans = sortednewscans;
Device.BeginInvokeOnMainThread(() => Published = false);
Device.BeginInvokeOnMainThread(() => LoadResults(RaceId));
Device.BeginInvokeOnMainThread(() => AddScanVisibility = false);
Device.BeginInvokeOnMainThread(() => IsBusy = false);
}
});
}
LoadResults方法
void LoadResults(int raceid)
{
var results = new ObservableCollection<Result>();
//Start with the timings
foreach (Timing timing in Timings)
{
var result = new Result();
//Basic details
result.RaceId = RaceId;
result.RaceDate = RaceDate;
result.Status = "Processing";
result.BackgroundColour = "White";
result.ScanTrashVisibility = true;
result.TimingTrashVisibility = true;
//Timing Data
result.TimingId = timing.Id;
result.TimingPosition = timing.Position;
result.TimingStatus = timing.Status;
result.StartTime = timing.StartTime;
result.EndTime = timing.EndTime;
result.TimingBatchCode = timing.BatchCode;
result.TimingBatchPosition = timing.BatchCode + timing.Position.ToString();
var elapsed = result.EndTime - result.StartTime;
string elapsedhours = elapsed.Hours.ToString();
string elapsedminutes = elapsed.Minutes.ToString();
string elapsedseconds = elapsed.Seconds.ToString();
string elapsedmillis;
if (elapsed.Milliseconds.ToString().Length > 2)
{
elapsedmillis = elapsed.Milliseconds.ToString().Substring(0, 2);
}
else
{
elapsedmillis = elapsed.Milliseconds.ToString();
}
if (elapsedhours.Length == 1) { elapsedhours = "0" + elapsedhours; }
if (elapsedminutes.Length == 1) { elapsedminutes = "0" + elapsedminutes; }
if (elapsedseconds.Length == 1) { elapsedseconds = "0" + elapsedseconds; }
if (elapsedmillis.Length == 1) { elapsedmillis = "0" + elapsedmillis; }
if((elapsedhours == "00"))
{
result.Elapsed = elapsedminutes + ":" + elapsedseconds + "." + elapsedmillis;
}
else
{
result.Elapsed = elapsedhours + ":" + elapsedminutes + ":" + elapsedseconds + "." + elapsedmillis;
}
results.Add(result);
}
//Add in the scans
foreach (Result result1 in results)
{
var scan = Scans.Where(p => p.BatchCode == result1.TimingBatchCode)
.FirstOrDefault(p => p.Position == result1.TimingPosition);
if (scan != null)
{
result1.ScanId = scan.Id;
result1.ScanPosition = scan.Position;
result1.ScanStatus = scan.Status;
result1.ScanBibNumber = scan.BibNumber;
result1.ScanBatchCode = scan.BatchCode;
result1.ScanBatchPosition = scan.BatchCode + scan.Position.ToString();
}
else
{
result1.ScanId = 0;
result1.ScanPosition = 0;
result1.ScanStatus = 99;
result1.ScanBibNumber = "UNKNOWN";
result1.AddScanButtonVisibility = true;
result1.ScanBatchCode = result1.TimingBatchCode;
}
}
//Add any scans which there are no times for
var notimescans = new ObservableCollection<Scan>();
foreach (Scan scan in Scans)
{
var checkscan = results.FirstOrDefault(s => s.ScanId == scan.Id);
if (checkscan == null)
{
var newresult = new Result();
newresult.RaceId = RaceId;
newresult.RaceDate = RaceDate;
newresult.Status = "Processing";
newresult.ScanId = scan.Id;
newresult.ScanPosition = scan.Position;
newresult.ScanStatus = scan.Status;
newresult.ScanBibNumber = scan.BibNumber;
newresult.ScanBatchCode = scan.BatchCode;
newresult.ScanBatchPosition = scan.BatchCode + scan.Position.ToString();
newresult.ScanTrashVisibility = true;
newresult.AddTimingButtonVisibility = true;
newresult.TimingId = 0;
newresult.TimingPosition = 99999;
newresult.TimingStatus = 99;
newresult.Elapsed = "N/A";
results.Add(newresult);
}
}
//Then add in the entries
foreach (Result result2 in results)
{
var entry = Entries.FirstOrDefault(p => p.BibNumber == result2.ScanBibNumber);
if (entry != null)
{
result2.EntryId = entry.Id;
result2.FirstName = entry.FirstName;
result2.LastName = entry.LastName;
result2.FormattedName = entry.FirstName + " " + entry.LastName.ToUpper();
result2.Gender = entry.Gender;
result2.DateOfBirth = entry.DateOfBirth;
result2.Club = entry.Club;
result2.Team = entry.Team;
result2.EntryBibNumber = entry.BibNumber;
if (result2.Club == null)
{
result2.FormattedClub = "";
}
else
{
result2.FormattedClub = entry.Club.ToUpper();
}
}
else
{
result2.EntryId = 0;
result2.FirstName = "Unknown";
result2.LastName = "ATHLETE";
result2.FormattedName = entry.FirstName + " " + entry.LastName.ToUpper();
result2.Gender = "Unknown";
result2.DateOfBirth = DateTime.Now;
result2.Club = "";
result2.Team = "";
result2.EntryBibNumber = result2.ScanBibNumber + " (Unrecognised)";
}
if(result2.ScanBatchCode == "NULLBATCH")
{
result2.ScanBatchCode = "Default";
}
if (result2.TimingBatchCode == "NULLBATCH")
{
result2.TimingBatchCode = "Default";
}
}
if(Scans.Count() != Timings.Count())
{
ResultsInvalid = true;
ResultsValidationError = "Your scan count and timing count's don't match. Please continue processing your results until these match and you will then be able to publish.";
}
else
{
Invalid = false;
PublishVisibility = true;
}
var sortedresults = new ObservableCollection<Result>(results.OrderBy(c => c.Elapsed));
int newposition = 1;
foreach (Result sortedresult in sortedresults)
{
sortedresult.OverallPosition = newposition;
newposition = newposition + 1;
}
//Create batches
grouped = new ObservableCollection<GroupedResultModel>();
foreach (Result result in results)
{
GroupedResultModel resultGroup = new GroupedResultModel();
var groupcheck = grouped.FirstOrDefault(b => b.BatchCode == result.ScanBatchCode);
if (groupcheck == null)
{
resultGroup.BatchCode = result.ScanBatchCode;
var BatchOfResults = results.Where(r => r.ScanBatchCode == resultGroup.BatchCode).OrderBy(r => r.Elapsed);
int batchposition = 1;
foreach (Result batchedresult in BatchOfResults)
{
batchedresult.OverallPosition = batchposition;
resultGroup.Add(batchedresult);
batchposition = batchposition + 1;
}
grouped.Add(resultGroup);
}
}
Results = sortedresults;
OnPropertyChanged("Invalid");
}