85 - Adding Editing Alarms
So did some more work on UI stuff today for my alarm clock, coolio. Today I built out the windows for adding/editing the three different kinds of alarms. I guess I'm not quite done yet though. After thinking about it I want to have some sort of audio alarm with it too. Not sure how rough that will be. I mean using a file picker wont be that hard, but playing the audio, not sure. Can't be that hard though right? Like usually, everything I worked on today has been uploaded to my GitHub. That reminds me, I need to look into is it okay to put not text files onto github, like images or audio files, hmmm. Just did some quick googling, still not sure. The image shouldn't be that big of a problem because it will just be a small image that will sit in the system tray. But a default audio alarm noise, not sure. Whatever I'll figure it out later. Okay let's move onto the code, let's go though the three different classes that run behind the xaml files. I'm not going to post the xaml because it's pretty uninteresting and there isn't much to talk about that we havn't already covered. Oh also, I ended up using WPF Toolkit library. It gave me a time and date selector, as well as a check combo box selector thing. It's a pretty nice library if you are doing WPF stuff. public Daily(AlarmTimer alarm, MainWindow window) { InitializeComponent(); Common(alarm, window); Time.Value = DateTime.Now; } public Daily(AlarmTimer alarm, MainWindow window, DateTime time, int id) { InitializeComponent(); Common(alarm, window); Edit = true; ID = id; Time.Value = time; } private void Common(AlarmTimer alarm, MainWindow window) { Alarm = alarm; Window = window; Show(); window.Hide(); } Okay let's first cover the constructors. The first one is used for making a new alarm, the second one is used for editing an alarm. Really all we do for a new alarm is set the Time Picker to now just so it has something and isn't a blank field. I could of used a default but meh, whatever. For edit we just make sure we set all the things on the window to what the alarm already is. In the Common method we are just saving variables we need, Alarm and window, and then make sure we make the window visible and hide the main window. private void Save(object sender, RoutedEventArgs e) { var time = (DateTime)Time.Value; if (Edit) { var temp = (DailyAlarm)Alarm.GetAlarm(ID); temp.SetTime(time.Hour, time.Minute); } else { var temp = new DailyAlarm(time.Hour, time.Minute); Alarm.AddAlarm(temp); } Window.AlarmGrid.Items.Refresh(); Window.Show(); Close(); } Okay now onto save, this is a little more interesting. We grab time first before checking if Edit is true or not, because either way we will need it. No reason to repeat code if you don't have to, and it doesn't take much work. If edit is true we just get the alarm that we are editing and call set time. If edit is false we make a new alarm with the time and add it to the alarm list. After that we just have to refresh the DataGrid we talked about last time so it updates, set the main window back to visible, and close out this window. public Weekly(AlarmTimer alarm, MainWindow window, List days, DateTime time, int id) { InitializeComponent(); ID = id; Edit = true; Time.Value = time; DayPicker.SelectedItemsOverride = days.Select(x => x.ToString()).ToList(); Common(alarm, window); } private void Common(AlarmTimer alarm, MainWindow window) { Alarm = alarm; Window = window; DayPicker.ItemsSource = Enum.GetNames(typeof(DayOfWeek)); Show(); window.Hide(); } Okay I skiped some stuff, mainly cause it was boring, so let's move onto Weekly alarms! Weekly is unique among the three alarms because the alarm is more then just a time/datetime. We have to take days of the week into consideration. I just realized I could of just passed in the Alarm and got all the elements here, and not have so many params in the method, oh well! Anyways, in the edit constructor we are really just looking at the second to last line. We need to pre-populate the Combo Check Box thing, and to do this we are just selecting the string of each object in the days list. We have to do this because it's a list of enums, and enums are ints. Now I could of done something where I had the value of the Combo Check Box to be ints and it display strings, but I couldn't figure it out in 5 seconds so I just did this. Next we need to look at Common, here to populate the values of the Combo Check Box we are getting the names on an enum. This is a pretty cool method and rarely comes up but is pretty useful. var days = new List(); foreach (var item in selectedDays) { var day = (DayOfWeek)System.Enum.Parse(typeof(DayOfWeek), item.ToString()); days.Add(day); } Okay this is taken from the save method in Weekly window. This is another cool thing with enums. As you can tell from the code before the Combo Check Box saves the values as strings, so we need to convert that string back into a int value that maps to an enum. So we call Enum.Parse pass it what enum and the string, then case it to that type of enum, and boom, we done! I'm not going to go into the Random window because it's pretty much the same thing as Daily, but it takes the full date into consideration. private void EditAlarm(object sender, RoutedEventArgs e) { var temp = (int)((Button)sender).CommandParameter; var alarm = Alarm.GetAlarm(temp); if (alarm.AlarmType == "Daily") new Daily(Alarm, this, alarm.GetAlarm(), alarm.ID); if (alarm.AlarmType == "Weekly") new Weekly(Alarm, this, ((WeeklyAlarm)alarm).GetDays() ,alarm.GetAlarm(), alarm.ID); if (alarm.AlarmType == "Random") new Random(Alarm, this, alarm.GetAlarm(), alarm.ID); } private void DeleteAlarm(object sender, RoutedEventArgs e) { var temp = (int)((Button)sender).CommandParameter; Alarm.RemoveAlarm(temp); } private void AddDailyAlarm(object sender, RoutedEventArgs e) { new Daily(Alarm, this); } Okay, last of the code for today. How are we calling this stuff? Well from last week you should remember every entry on the data grid has an edit and delete button, and we make sure to have the ID at the ready. For edit we get the ID from the Command Parameter and then get the alarm with that ID. And because we have that variable for AlarmType we can just use a few if statements to figure out which Alarm Type it is and call the correct constructor. For Delete we just get the ID and call RemoveAlarm on that ID. Then for the three different AddBlankAlarm we just call the basic constructor for whatever relevant alarm window. I didn't post the other two create methods because they are basically the same, just new Weekly() and new Random(). Here is what the three windows ended up looking like. I got to be honest, I'm a little sad I'm not going to be working on this tomorrow. I've had a lot of fun with this little project, but my main goal is to work on my video game and finish that. I'm not exactly sure what I'm doing for a blog post tomorrow. I'm just going to be following a tutorial so I'm not sure if it would make sense to post code and talk about it. I guess I'll have to figure that out tomorrow. Anyways, cya, have a good day.
4/12/2018 10:49:55 PM

Add Comment Auther