/// <summary> /// Handle the new member button click event. /// </summary> /// <param name="sender"></param> /// <param name="args"></param> private void OnNewMemberButton(object sender, RoutedEventArgs args) { Team team = (Team)TeamSelectionComboBox.SelectedItem; MemberTab memberTab = (MemberTab)MemberTypeTabControl.SelectedItem; Member newMember = (Member)Activator.CreateInstance(memberTab.MemberType); team.AddMember(memberTab.MemberType, newMember); // Find a child data-grid of the tab control DataGrid membersDataGrid = (DataGrid)MemberTypeTabControl.GetChildren().Find(control => control is DataGrid); membersDataGrid.SelectedItem = newMember; membersDataGrid.ScrollIntoView(newMember); }
/// <summary> /// Handle the type selection changed. /// </summary> /// <param name="sender"></param> /// <param name="args"></param> private void OnTypeSelectionChanged(object sender, SelectionChangedEventArgs args) { // Find a child data-grid of the tab control DataGrid membersDataGrid = (DataGrid)MemberTypeTabControl.GetChildren().Find(control => control is DataGrid); if (membersDataGrid.SelectedItem == null) { return; } Type newType = (Type)TypeSelectionComboBox.SelectedItem; Member member = (Member)membersDataGrid.SelectedItem; // No change in type means that we don't need to do anything if (newType == member.GetType()) { return; } Team team = (Team)TeamSelectionComboBox.SelectedItem; // Remove the member from the old type and move it to the new type collection in the team member map team.RemoveMember(member.GetType(), member); // Convert the member to its respective type via casting Member newMember = new Member(); if (newType == typeof(Wrestler)) { newMember = new Wrestler(); } else if (newType == typeof(Coach)) { newMember = new Coach(); } // Copy the values from the old member to the converted member newMember.FirstName = member.FirstName; newMember.LastName = member.LastName; newMember.Gender = member.Gender; newMember.School = member.School; newMember.YearsOfExperience = member.YearsOfExperience; team.AddMember(newType, newMember); }
/// <summary> /// Loads a <see cref="Team"/> from the data file at the specified <paramref name="filepath"/>. /// </summary> /// <remarks> /// In most cases, even if there is an error reading a specific line of the data file, /// the rest of the file will stead be read since that data could fine; hence, the return value /// will often not be <value>null</value>, even if errors were encountered. /// </remarks> /// <param name="filepath">The path to the data file.</param> /// <returns>A <see cref="Team"/> object containing the loaded data or <value>null</value> if the <see cref="Team"/> could not be loaded.</returns> public static Team Load(string filepath) { if (!File.Exists(filepath)) { Logger.Log(string.Empty, $"Failed to load team: data file (\"{filepath}\") does not exist.", LoggerVerbosity.Error, LoggerDestination.Form); return(null); } // While there are manual sanity checks during deserialization, // let's wrap the deserialization procedure in a try-catch block // so that we can catch any missed exceptions. Since an exception // caught by this try-catch is unexpected, if it does happen, it is // treated as severe and ends the loading of the file (returns null). try { // The name of the team is the same as the data file name without its extension. Team result = new Team(Path.GetFileNameWithoutExtension(filepath), filepath); int errorCount = 0; string[] lines = File.ReadAllLines(filepath); for (int i = 0; i < lines.Length; i++) { // The team format consists of a set of lines where each // line contains a set of comma-separated values, with the first // value indicating the type of the member: "Coach" or "Wrestler" string line = lines[i]; string[] components = line.Split(','); // Temporary error message buffer used to reduce // string interning overhead string errorMessage; // Check if our line is empty or consists of no comma-separated values. // If this is the case, skip this line and continue reading the file and log // the error. This is not very severe so we don't log the error to the form via // message box. if (components.Length == 0) { errorMessage = $"Encountered empty line on line {i + 1}.\n\n(\"{filepath}\")"; Logger.LogFunctionEntry(string.Empty, errorMessage, LoggerVerbosity.Warning); errorCount += 1; continue; } string lineWithoutType = line.Substring(components[0].Length + 1); // If we encounter a member type that is not "Coach" or "Wrestler", let's log this encounter // and the line that it occured, and then continue reading the file. This sort of error is not // very severe since it only affects a single line; that is, the rest of the data might still be A-OK. switch (components[0]) { case Coach.SerializationTypeTag: Coach coach = new Coach(); if (!coach.Load(lineWithoutType)) { errorMessage = $"Failed to load Coach on line {i + 1}."; Logger.LogFunctionEntry(string.Empty, errorMessage, LoggerVerbosity.Error); errorCount += 1; } result.AddMember(coach); break; case Wrestler.SerializationTypeTag: Wrestler wrestler = new Wrestler(); if (!wrestler.Load(lineWithoutType)) { errorMessage = $"Failed to load Wrestler on line {i + 1}."; Logger.LogFunctionEntry(string.Empty, errorMessage, LoggerVerbosity.Error); errorCount += 1; } result.AddMember(wrestler); break; default: Logger.LogFunctionEntry(string.Empty, $"Encountered unknown member type (\"{components[0]}\") while " + $"loading a team data file on line {i + 1}.\n(\"{filepath}\")", LoggerVerbosity.Warning); errorCount += 1; break; } } if (errorCount > 0) { Logger.Log(string.Empty, $"{errorCount} errors while loading team!\n\nView log for more details.", LoggerVerbosity.Warning, LoggerDestination.Form); } return(result); } catch (Exception exception) { Logger.Log(exception.Message, LoggerVerbosity.Error); Logger.Log(string.Empty, $"Caught exception while loading team. Team could not be loaded.\n\nView log for more details.", LoggerVerbosity.Error, LoggerDestination.Form); return(null); } }