Vereinsmeisterschaften  22aa7800eae54b428d40e835886cefe1fdefdfdf
This is a software that can be used to manage the internal competition of the swimming club Illertissen called "Vereinsmeisterschaften".
Loading...
Searching...
No Matches
PrepareRacesViewModel.cs
1using System.Collections.ObjectModel;
2using System.Windows.Input;
3using CommunityToolkit.Mvvm.ComponentModel;
4using CommunityToolkit.Mvvm.Input;
5using MahApps.Metro.Controls.Dialogs;
12
14
18public class PrepareRacesViewModel : ObservableObject, INavigationAware
19{
20 #region Calculated Races
21
25 public ObservableCollection<RacesVariant> AllRacesVariants => _raceService?.AllRacesVariants;
26
31
35 public bool AreFriendGroupsAvailable => _personService.NumberFriendGroups > 0;
36
37 // ----------------------------------------------------------------------------------------------------------------------------------------------
38
45 {
46 get => CurrentRacesVariant?.VariantID ?? -1;
47 set
48 {
49 if (value > 0)
50 {
51 CurrentRacesVariant = AllRacesVariants?.Where(r => r.VariantID == value).FirstOrDefault();
52 }
53 else if(value == 0)
54 {
55 CurrentRacesVariant = (_raceService?.PersistedRacesVariant != null) ? _raceService?.PersistedRacesVariant : AllRacesVariants?.FirstOrDefault();
56 }
57 else
58 {
60 }
61 OnPropertyChanged();
62 }
63 }
64
65 // ----------------------------------------------------------------------------------------------------------------------------------------------
66
67 private RacesVariant _currentRacesVariant;
72 {
73 get => _currentRacesVariant;
74 set
75 {
76 if (SetProperty(ref _currentRacesVariant, value, new RacesVariantFullEqualityComparer()))
77 {
78 _currentRacesVariant?.UpdateNotAssignedStarts(_personService.GetAllPersonStarts());
79 OnPropertyChanged(nameof(CurrentRacesVariantIsPersistent));
80 }
81 }
82 }
83
84 // ----------------------------------------------------------------------------------------------------------------------------------------------
85
89 private void recalculateVariantIDs()
90 {
91 int currentID = CurrentVariantID;
92 CurrentVariantID = -1; // Set to -1 to clear the current selection in the combobox
93 int newVariantID = _raceService?.RecalculateVariantIDs(currentID) ?? -1;
94 CurrentVariantID = newVariantID == -1 ? 0 : newVariantID; // If newVariantID is -1, select the persisted race or first element instead of nothing
95 OnPropertyChanged(nameof(AllRacesVariants));
96 OnPropertyChanged(nameof(AreRacesVariantsAvailable));
97 }
98
99 // ----------------------------------------------------------------------------------------------------------------------------------------------
100
106 {
107 get => CurrentRacesVariant?.IsPersistent ?? false;
108 set
109 {
110 if (CurrentRacesVariant != null)
111 {
112 foreach (RacesVariant item in AllRacesVariants)
113 {
114 item.IsPersistent = false;
115 }
116 CurrentRacesVariant.IsPersistent = value;
117 }
118 OnPropertyChanged();
119 }
120 }
121
122 #endregion
123
124 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
125
126 #region Highlight Feature
127
128 private HighlightPersonStartModes _highlightPersonStartMode;
133 {
134 get => _highlightPersonStartMode;
135 set
136 {
137 if (SetProperty(ref _highlightPersonStartMode, value))
138 {
140 }
141 }
142 }
143
144 // ----------------------------------------------------------------------------------------------------------------------------------------------
145
149 public List<Person> AvailablePersons => _personService?.GetPersons().OrderBy(p => p.Name).ToList();
150
151 private Person _highlightedPerson;
156 {
157 get => _highlightedPerson;
158 set
159 {
160 if (SetProperty(ref _highlightedPerson, value))
161 {
163 }
164 }
165 }
166
167 // ----------------------------------------------------------------------------------------------------------------------------------------------
168
169 private List<SwimmingStyles> _availableSwimmingStyles = Enum.GetValues(typeof(SwimmingStyles)).Cast<SwimmingStyles>().Where(s => s != SwimmingStyles.Unknown).ToList();
173 public List<SwimmingStyles> AvailableSwimmingStyles => _availableSwimmingStyles;
174
175 private SwimmingStyles _highlightedSwimmingStyle;
180 {
181 get => _highlightedSwimmingStyle;
182 set
183 {
184 if (SetProperty(ref _highlightedSwimmingStyle, value))
185 {
187 }
188 }
189 }
190
191 // ----------------------------------------------------------------------------------------------------------------------------------------------
192
193 private Genders _highlightedGender;
198 {
199 get => _highlightedGender;
200 set
201 {
202 if (SetProperty(ref _highlightedGender, value))
203 {
205 }
206 }
207 }
208
209 // ----------------------------------------------------------------------------------------------------------------------------------------------
210
211 private ushort _highlightedDistance;
216 {
217 get => _highlightedDistance;
218 set
219 {
220 if (SetProperty(ref _highlightedDistance, value))
221 {
223 }
224 }
225 }
226
227 // ----------------------------------------------------------------------------------------------------------------------------------------------
228
233 {
234 List<PersonStart> personStarts = _personService.GetAllPersonStarts();
235 foreach (PersonStart personStart in personStarts)
236 {
238 {
239 case HighlightPersonStartModes.Person: personStart.IsHighlighted = personStart.PersonObj.Equals(HighlightedPerson); break;
240 case HighlightPersonStartModes.SwimmingStyle: personStart.IsHighlighted = personStart.Style.Equals(HighlightedSwimmingStyle); break;
241 case HighlightPersonStartModes.Gender: personStart.IsHighlighted = personStart.PersonObj.Gender.Equals(HighlightedGender); break;
242 case HighlightPersonStartModes.Distance: personStart.IsHighlighted = personStart.CompetitionObj?.Distance == HighlightedDistance; break;
243 case HighlightPersonStartModes.None: personStart.IsHighlighted = false; break;
244 default: personStart.IsHighlighted = false; break;
245 }
246 }
247 }
248
249 #endregion
250
251 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
252
253 private IRaceService _raceService;
254 private IWorkspaceService _workspaceService;
255 private IPersonService _personService;
256 private IDialogCoordinator _dialogCoordinator;
257 private ShellViewModel _shellVM;
258
267 public PrepareRacesViewModel(IRaceService raceService, IWorkspaceService workspaceService, IPersonService personService, IDialogCoordinator dialogCoordinator, ShellViewModel shellVM)
268 {
269 _raceService = raceService;
270 _workspaceService = workspaceService;
271 _personService = personService;
272 _dialogCoordinator = dialogCoordinator;
273 _shellVM = shellVM;
274
275 _raceService.PropertyChanged += (sender, e) =>
276 {
277 switch (e.PropertyName)
278 {
279 case nameof(RaceService.AllRacesVariants):
280 OnPropertyChanged(nameof(CurrentRacesVariant));
281 OnPropertyChanged(nameof(AllRacesVariants));
282 OnPropertyChanged(nameof(AreRacesVariantsAvailable));
283 break;
285 OnPropertyChanged(nameof(CurrentRacesVariant));
286 break;
287 default:
288 break;
289 }
290 };
291 _raceService.AllRacesVariants.CollectionChanged += (sender, e) =>
292 {
293 ((RelayCommand)AddNewRaceCommand).NotifyCanExecuteChanged();
294 ((RelayCommand)CleanupRacesCommand).NotifyCanExecuteChanged();
295 ((RelayCommand)RemoveRaceVariantCommand).NotifyCanExecuteChanged();
296 ((RelayCommand)ReorderRaceVariantsCommand).NotifyCanExecuteChanged();
297 };
298 }
299
300 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
301
302 #region Calculate Races Variants Command
303
304 private ICommand _calculateRacesVariantsCommand;
308 public ICommand CalculateRacesVariantsCommand => _calculateRacesVariantsCommand ?? (_calculateRacesVariantsCommand = new RelayCommand(async() =>
309 {
310 DoubleProgressDialog _progressDialog = new DoubleProgressDialog();
311 _progressDialog.Title = Properties.Resources.CalculateRacesVariantsString;
312 _progressDialog.ProgressDescription1 = Properties.Resources.IterationProgressString;
313 _progressDialog.ProgressDescription2 = Properties.Resources.SolutionProgressString;
314 _progressDialog.ProgressNumberDecimals = 1;
315
316 double nextProgressLevelIteration = 0.0;
317 ProgressDelegate onProgressIteration = (sender, progress, currentStep) =>
318 {
319 if (progress >= nextProgressLevelIteration)
320 {
321 nextProgressLevelIteration += 0.1; // Only report all 0.1%. This is enough.
322 _progressDialog.Progress1 = progress;
323 }
324 };
325 double nextProgressLevelSolution = 0.0;
326 ProgressDelegate onProgressSolution = (sender, progress, currentStep) =>
327 {
328 if (progress >= nextProgressLevelSolution)
329 {
330 nextProgressLevelSolution += 0.5; // Only report all 0.5%. This is enough.
331 _progressDialog.Progress2 = progress;
332 }
333 };
334
335 CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
336 _progressDialog.OnCanceled += (sender, e) => cancellationTokenSource.Cancel();
337 await _dialogCoordinator.ShowMetroDialogAsync(_shellVM, _progressDialog);
338
339 try
340 {
341 await _raceService.CalculateRacesVariants(cancellationTokenSource.Token, onProgressIteration, onProgressSolution);
343
344 await _dialogCoordinator.HideMetroDialogAsync(_shellVM, _progressDialog);
345
346 int numberVariants = AllRacesVariants.Count;
347 ushort numberRequestedVariants = _workspaceService?.Settings?.GetSettingValue<ushort>(WorkspaceSettings.GROUP_RACE_CALCULATION, WorkspaceSettings.SETTING_RACE_CALCULATION_NUM_RACE_VARIANTS_AFTER_CALCULATION) ?? 0;
348 if (numberVariants < numberRequestedVariants)
349 {
350 // Less variants than required are calculated
351 await _dialogCoordinator.ShowMessageAsync(_shellVM, Properties.Resources.CalculateRacesVariantsString, string.Format(Properties.Resources.CalculationWarningTooLessVariantsString, numberVariants, numberRequestedVariants));
352 }
353 }
354 catch (OperationCanceledException)
355 {
356 await _dialogCoordinator.HideMetroDialogAsync(_shellVM, _progressDialog);
357 }
358 catch (Exception ex)
359 {
360 await _dialogCoordinator.HideMetroDialogAsync(_shellVM, _progressDialog);
361 await _dialogCoordinator.ShowMessageAsync(_shellVM, Properties.Resources.ErrorString, ex.Message);
362 }
363 }));
364#endregion
365
366 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
367
368 #region Other Commands
369
370 private ICommand _addNewRaceCommand;
374 public ICommand AddNewRaceCommand => _addNewRaceCommand ?? (_addNewRaceCommand = new RelayCommand(() =>
375 {
376 if(CurrentRacesVariant != null)
377 {
378 CurrentRacesVariant.Races.Add(new Race());
379 }
380 }, () => AreRacesVariantsAvailable));
381
382 // ----------------------------------------------------------------------------------------------------------------------------------------------
383
384 private ICommand _cleanupRacesCommand;
388 public ICommand CleanupRacesCommand => _cleanupRacesCommand ?? (_cleanupRacesCommand = new RelayCommand(() =>
389 {
390 _raceService?.CleanupRacesVariants();
391 }, () => AreRacesVariantsAvailable));
392
393 // ----------------------------------------------------------------------------------------------------------------------------------------------
394
395 private ICommand _addNewRaceVariantCommand;
399 public ICommand AddNewRaceVariantCommand => _addNewRaceVariantCommand ?? (_addNewRaceVariantCommand = new RelayCommand(() =>
400 {
401 RacesVariant newVariant = new RacesVariant(_workspaceService);
402 _raceService?.AddRacesVariant(newVariant);
403 CurrentRacesVariant = newVariant;
404 OnPropertyChanged(nameof(AreRacesVariantsAvailable));
405 OnPropertyChanged(nameof(CurrentRacesVariant));
406 OnPropertyChanged(nameof(AllRacesVariants));
407 OnPropertyChanged(nameof(CurrentVariantID));
408 }));
409
410 // ----------------------------------------------------------------------------------------------------------------------------------------------
411
412 private ICommand _removeRaceVariantCommand;
416 public ICommand RemoveRaceVariantCommand => _removeRaceVariantCommand ?? (_removeRaceVariantCommand = new RelayCommand(async () =>
417 {
418 // Ask the user for deletion confirmation
419 MessageDialogResult result = await _dialogCoordinator.ShowMessageAsync(_shellVM, Properties.Resources.DeleteConfirmationTitleString,
421 MessageDialogStyle.AffirmativeAndNegative,
422 new MetroDialogSettings() { AffirmativeButtonText = Properties.Resources.RemoveRaceVariantString, NegativeButtonText = Properties.Resources.CancelString });
423
424 if (result == MessageDialogResult.Affirmative)
425 {
426 int index = AllRacesVariants.IndexOf(CurrentRacesVariant);
427 _raceService?.RemoveRacesVariant(CurrentRacesVariant);
428 if (index == AllRacesVariants.Count && AllRacesVariants.Count >= 1)
429 {
430 index--;
431 }
432 CurrentRacesVariant = null; // Set to null and then to the correct value to update the combobox on the view
433 CurrentRacesVariant = (index >= 0 && index < AllRacesVariants.Count) ? AllRacesVariants[index] : AllRacesVariants?.FirstOrDefault();
434 OnPropertyChanged(nameof(AreRacesVariantsAvailable));
435 OnPropertyChanged(nameof(CurrentRacesVariant));
436 OnPropertyChanged(nameof(AllRacesVariants));
437 OnPropertyChanged(nameof(CurrentVariantID));
438 }
439 }, () => AreRacesVariantsAvailable));
440
441 // ----------------------------------------------------------------------------------------------------------------------------------------------
442
443 private ICommand _copyRaceVariantCommand;
447 public ICommand CopyRaceVariantCommand => _copyRaceVariantCommand ?? (_copyRaceVariantCommand = new RelayCommand(() =>
448 {
449 RacesVariant copyVariant = new RacesVariant(CurrentRacesVariant, true, false, _workspaceService);
450 _raceService?.AddRacesVariant(copyVariant);
451 CurrentRacesVariant = copyVariant;
452 OnPropertyChanged(nameof(AreRacesVariantsAvailable));
453 OnPropertyChanged(nameof(CurrentRacesVariant));
454 OnPropertyChanged(nameof(AllRacesVariants));
455 OnPropertyChanged(nameof(CurrentVariantID));
456 }, () => CurrentRacesVariant != null));
457
458 // ----------------------------------------------------------------------------------------------------------------------------------------------
459
460 private ICommand _reorderRaceVariantsCommand;
464 public ICommand ReorderRaceVariantsCommand => _reorderRaceVariantsCommand ?? (_reorderRaceVariantsCommand = new RelayCommand(() =>
465 {
466 _raceService?.SortVariantsByScore();
468 }, () => AreRacesVariantsAvailable));
469
470 #endregion
471
472 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
473
475 public void OnNavigatedTo(object parameter)
476 {
477 _raceService.CleanupRacesVariants(false);
478 _raceService.RecalculateVariantIDs();
479
480 ushort numSwimLanes = _workspaceService?.Settings?.GetSettingValue<ushort>(WorkspaceSettings.GROUP_RACE_CALCULATION, WorkspaceSettings.SETTING_RACE_CALCULATION_NUMBER_OF_SWIM_LANES) ?? 0;
481 DropAllowedHandler.Instance.MaxItemsInTargetCollection = numSwimLanes;
482
483 OnPropertyChanged(nameof(AllRacesVariants));
484 OnPropertyChanged(nameof(AreRacesVariantsAvailable));
485 OnPropertyChanged(nameof(AvailablePersons));
486 OnPropertyChanged(nameof(CurrentRacesVariant));
487 OnPropertyChanged(nameof(AreFriendGroupsAvailable));
489 }
490
492 public void OnNavigatedFrom()
493 {
494 }
495}
Interaktionslogik für DoubleProgressDialog.xaml.
ushort Distance
Distance in meters for this competition (e.g.
Class describing a start of a person.
Definition PersonStart.cs:9
Competition CompetitionObj
Reference to the competition object to which the start belongs.
override bool Equals(object obj)
Compare if two PersonStarts are equal.
Class that represents a single race.
Definition Race.cs:12
Comparer that only uses most properties of a RacesVariant to determine equality:
Class that represents a combination variant of all single races.
Service used to manage Race and RacesVariant objects.
ObservableCollection< RacesVariant > AllRacesVariants
List with all RacesVariant (including the loaded and calculated ones)
RacesVariant PersistedRacesVariant
RacesVariant object that is persisted (saved/loaded to/from a file).
Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
static string SolutionProgressString
Sucht eine lokalisierte Zeichenfolge, die Solution Progress ähnelt.
static string CalculationWarningTooLessVariantsString
Sucht eine lokalisierte Zeichenfolge, die Less variants than requested were calculated ({0}...
static string IterationProgressString
Sucht eine lokalisierte Zeichenfolge, die Iteration Progress ähnelt.
static string CancelString
Sucht eine lokalisierte Zeichenfolge, die Cancel ähnelt.
static string CalculateRacesVariantsString
Sucht eine lokalisierte Zeichenfolge, die Calculate Races Variants ähnelt.
static string DeleteConfirmationTitleString
Sucht eine lokalisierte Zeichenfolge, die Really delete?
static string DeleteRaceVariantConfirmationString
Sucht eine lokalisierte Zeichenfolge, die Really delete the selected variant?
static string ErrorString
Sucht eine lokalisierte Zeichenfolge, die Error ähnelt.
static string RemoveRaceVariantString
Sucht eine lokalisierte Zeichenfolge, die Remove Variant ähnelt.
ICommand AddNewRaceVariantCommand
Add a new RacesVariant element to the RaceService.AllRacesVariants
bool CurrentRacesVariantIsPersistent
Property wrapper for the RacesVariant.IsPersistent property of the CurrentRacesVariant.
bool AreFriendGroupsAvailable
True, if there are friend groups available in the IPersonService
bool AreRacesVariantsAvailable
True, if there is at least one element in AllRacesVariants
ICommand AddNewRaceCommand
Command to add a new Race to the CurrentRacesVariant
void recalculateVariantIDs()
Recalculate the variant IDs for all elements in AllRacesVariants
void recalculateHighlightedPersonStarts()
Recalculate the PersonStart.IsHighlighted property for all PersonStart objects depending on the Highl...
void OnNavigatedFrom()
OnNavigatedFrom method to handle navigation away from this object.
ICommand ReorderRaceVariantsCommand
Reorder the RacesVariant variants by score and then recalculate the variant IDs.
ICommand CleanupRacesCommand
Command to cleanup all RacesVariant in RaceService.AllRacesVariants
Genders HighlightedGender
All PersonStart elements that match this Genders will be highlighted if the HighlightPersonStartMode ...
Person HighlightedPerson
All PersonStart elements that match this Person will be highlighted if the HighlightPersonStartMode i...
PrepareRacesViewModel(IRaceService raceService, IWorkspaceService workspaceService, IPersonService personService, IDialogCoordinator dialogCoordinator, ShellViewModel shellVM)
Constructor of the prepare races view model.
ICommand CalculateRacesVariantsCommand
Command to calculate new RacesVariant variants.
int CurrentVariantID
RacesVariant.VariantID of the CurrentRacesVariant Use 0 to select the RaceService....
SwimmingStyles HighlightedSwimmingStyle
All PersonStart elements that match this SwimmingStyles will be highlighted if the HighlightPersonSta...
List< Person > AvailablePersons
List with all available Person objects.
RacesVariant CurrentRacesVariant
RacesVariant that is currently displayed on the view
ICommand CopyRaceVariantCommand
Copy the CurrentRacesVariant and add it as new variant to RaceService.AllRacesVariants
List< SwimmingStyles > AvailableSwimmingStyles
List with all available SwimmingStyles
ObservableCollection< RacesVariant > AllRacesVariants
List with all RacesVariant
HighlightPersonStartModes HighlightPersonStartMode
Currently active highlight mode.
ICommand RemoveRaceVariantCommand
Remove the CurrentRacesVariant from the RaceService.AllRacesVariants
void OnNavigatedTo(object parameter)
OnNavigatedTo method to handle navigation to this object.
ushort HighlightedDistance
All PersonStart elements that match this distance will be highlighted if the HighlightPersonStartMode...
ViewModel for the main shell of the application.
Interface for objects that need to handle navigation events.
Interface for a service used to get and store a list of Person objects.
Interface for a service used to manage Race and RacesVariant objects.
Interface for a service used to manage a workspace.
delegate void ProgressDelegate(object sender, float progress, string currentStep="")
Delegate void for progress changes.
SwimmingStyles
Available swimming styles.
Genders
Available genders for a person.
Definition Genders.cs:7
HighlightPersonStartModes
Enum to define the different modes to highlight a PersonStart
@ Person
Highlight all PersonStart objects that have the same Person object.