// Run when a tile is pressed on the timetable private void Timetable_TileClicked(TimetableTile Tile) { // If the current user isn't a student and either there's no booking or the teacher owns the booking if (!CurrentUser.IsStudent && (CurrentUser.IsAdmin || Tile.Booking == null || Tile.Booking.Teacher.Id == CurrentUser.Id)) { EditBooking Window = null; // Whether this is a new booking or an edited one bool NewBooking = Tile.Booking == null; if (NewBooking) // New booking Window = new EditBooking(CurrentUser, true, Tile.Time, Tile.Room); else // Editing booking Window = new EditBooking(CurrentUser, false, Tile.Booking); Window.CurrentDate = CurrentDay; // Display the window, store the result bool? Result = Window.ShowDialog(); // If the window closed successfully if (Result.HasValue && Result.Value) { // Retrieve the new item Booking b = Window.GetItem(); if (b == null) return; // Are we deleting? bool Delete = Window.DeleteBooking; b.Id = Tile.Booking == null ? 0 : Tile.Booking.Id; // Add or remove as appropriate using (DataRepository Repo = new DataRepository()) { if (Delete) Repo.Bookings.Remove(Repo.Bookings.Where(b2 => b2.Id == b.Id).Single()); else Repo.Bookings.Add(b); } } } }
// Organises the table for a given user on a particular day public void SetTimetable(User CurrentUser, DateTime Day) { // Get the current database state DataSnapshot Frame = DataRepository.TakeSnapshot(); // Generate the correct number of rows Container.RowDefinitions.Clear(); // Top header row Container.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) }); // Actual rows of the table for (int y = 0; y < Frame.Rooms.Count; y++) Container.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(TileHeight) }); // Generate the columns Container.ColumnDefinitions.Clear(); // Left-hand side-heading column Container.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(LeftWidth) }); // Actual columns in the table for (int x = 0; x < Frame.Periods.Count; x++) Container.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(TileWidth) }); // Add the left-hand bar, contains room names and a tooltip Container.Children.Clear(); for (int y = 0; y < Frame.Rooms.Count; y++) { // Create a textblock displaying the room name TextBlock Child = new TextBlock(); Child.Text = Frame.Rooms[y].RoomName; // Set standard font, margin, wrapping style etc Child.FontSize = 16; Child.Margin = new Thickness(0, 0, 5, 0); Child.TextWrapping = TextWrapping.Wrap; Child.VerticalAlignment = VerticalAlignment.Center; Child.HorizontalAlignment = HorizontalAlignment.Right; // Create the alignment control for nice layout Border LeftTile = new Border(); // Set tooltip to useful information LeftTile.ToolTip = "Standard Seats: " + Frame.Rooms[y].StandardSeats + (Frame.Rooms[y].SpecialSeats == 0 ? "" : "\n" + Frame.Rooms[y].SpecialSeatType + ": " + Frame.Rooms[y].SpecialSeats); // Set the UI child of this control to be the texblock above LeftTile.Child = Child; // Background colour LeftTile.Background = MarginBrush; // Positioning on the layout grid LeftTile.SetValue(Grid.RowProperty, y + 1); LeftTile.SetValue(Grid.ColumnProperty, 0); // Add the controls to the grid Container.Children.Add(LeftTile); } // Add the top heading, contains timeslot name and time interval for (int x = -1; x < Frame.Periods.Count; x++) { // Use a grid for ease of layout Grid TopTile = new Grid(); TopTile.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) }); TopTile.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) }); // Set background and child alignments TopTile.Background = MarginBrush; TopTile.VerticalAlignment = VerticalAlignment.Bottom; TopTile.HorizontalAlignment = HorizontalAlignment.Left; // If we're not filling out the top-left corner cell, store the timeslot name string Text = ""; if (x >= 0 && !string.IsNullOrWhiteSpace(Frame.Periods[x].Name)) Text = Frame.Periods[x].Name; // First textblock - timeslot name TopTile.Children.Add(new TextBlock() { Text = Text, FontSize = 16, Margin = new Thickness(2, 2, 2, 0), TextWrapping = TextWrapping.Wrap, Width = TileWidth }); // Second textblock - timeslot duration TopTile.Children.Add(new TextBlock() { Text = x >= 0 ? Frame.Periods[x].TimeRange : "", FontSize = 16, Margin = new Thickness(2, 0, 2, 10), TextWrapping = TextWrapping.Wrap, Width = TileWidth }); // Set the position of each textblock within the local grid for (int y = 0; y < TopTile.Children.Count; y++) TopTile.Children[y].SetValue(Grid.RowProperty, y); // Algin the local grid within the table's grid TopTile.SetValue(Grid.RowProperty, 0); TopTile.SetValue(Grid.ColumnProperty, x + 1); Container.Children.Add(TopTile); } // Add the main content // Find bookings on this day List<Booking> RelevantBookings = Frame.Bookings.Where(b => b.MatchesDay(Day)).ToList(); // Initialise the internal array of tiles Tiles = new TimetableTile[Frame.Rooms.Count, Frame.Periods.Count]; for (int y = 0; y < Frame.Rooms.Count; y++) { for (int x = 0; x < Frame.Periods.Count; x++) { // Get the booking (or null) for this combination of room and timeslot Booking Current = RelevantBookings.Where(b => b.TimeSlot == Frame.Periods[x] && b.Rooms.Contains(Frame.Rooms[y])).SingleOrDefault(); // Create the timetable tile Tiles[y, x] = new TimetableTile(Current, Frame.Periods[x], Frame.Rooms[y], CurrentUser); // Layout Container.Children.Add(Tiles[y, x]); Tiles[y, x].SetValue(Grid.RowProperty, y + 1); Tiles[y, x].SetValue(Grid.ColumnProperty, x + 1); // Hook up the tile clicked handler Tiles[y, x].MouseLeftButtonDown += (o, e) => TileClicked((TimetableTile)o); } } }
// Organises the table for a given user on a particular day public void SetTimetable(User CurrentUser, DateTime Day) { // Get the current database state DataSnapshot Frame = DataRepository.TakeSnapshot(); // Generate the correct number of rows Container.RowDefinitions.Clear(); // Top header row Container.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) }); // Actual rows of the table for (int y = 0; y < Frame.Rooms.Count; y++) { Container.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(TileHeight) }); } // Generate the columns Container.ColumnDefinitions.Clear(); // Left-hand side-heading column Container.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(LeftWidth) }); // Actual columns in the table for (int x = 0; x < Frame.Periods.Count; x++) { Container.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(TileWidth) }); } // Add the left-hand bar, contains room names and a tooltip Container.Children.Clear(); for (int y = 0; y < Frame.Rooms.Count; y++) { // Create a textblock displaying the room name TextBlock Child = new TextBlock(); Child.Text = Frame.Rooms[y].RoomName; // Set standard font, margin, wrapping style etc Child.FontSize = 16; Child.Margin = new Thickness(0, 0, 5, 0); Child.TextWrapping = TextWrapping.Wrap; Child.VerticalAlignment = VerticalAlignment.Center; Child.HorizontalAlignment = HorizontalAlignment.Right; // Create the alignment control for nice layout Border LeftTile = new Border(); // Set tooltip to useful information LeftTile.ToolTip = "Standard Seats: " + Frame.Rooms[y].StandardSeats + (Frame.Rooms[y].SpecialSeats == 0 ? "" : "\n" + Frame.Rooms[y].SpecialSeatType + ": " + Frame.Rooms[y].SpecialSeats); // Set the UI child of this control to be the texblock above LeftTile.Child = Child; // Background colour LeftTile.Background = MarginBrush; // Positioning on the layout grid LeftTile.SetValue(Grid.RowProperty, y + 1); LeftTile.SetValue(Grid.ColumnProperty, 0); // Add the controls to the grid Container.Children.Add(LeftTile); } // Add the top heading, contains timeslot name and time interval for (int x = -1; x < Frame.Periods.Count; x++) { // Use a grid for ease of layout Grid TopTile = new Grid(); TopTile.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) }); TopTile.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) }); // Set background and child alignments TopTile.Background = MarginBrush; TopTile.VerticalAlignment = VerticalAlignment.Bottom; TopTile.HorizontalAlignment = HorizontalAlignment.Left; // If we're not filling out the top-left corner cell, store the timeslot name string Text = ""; if (x >= 0 && !string.IsNullOrWhiteSpace(Frame.Periods[x].Name)) { Text = Frame.Periods[x].Name; } // First textblock - timeslot name TopTile.Children.Add(new TextBlock() { Text = Text, FontSize = 16, Margin = new Thickness(2, 2, 2, 0), TextWrapping = TextWrapping.Wrap, Width = TileWidth }); // Second textblock - timeslot duration TopTile.Children.Add(new TextBlock() { Text = x >= 0 ? Frame.Periods[x].TimeRange : "", FontSize = 16, Margin = new Thickness(2, 0, 2, 10), TextWrapping = TextWrapping.Wrap, Width = TileWidth }); // Set the position of each textblock within the local grid for (int y = 0; y < TopTile.Children.Count; y++) { TopTile.Children[y].SetValue(Grid.RowProperty, y); } // Algin the local grid within the table's grid TopTile.SetValue(Grid.RowProperty, 0); TopTile.SetValue(Grid.ColumnProperty, x + 1); Container.Children.Add(TopTile); } // Add the main content // Find bookings on this day List <Booking> RelevantBookings = Frame.Bookings.Where(b => b.MatchesDay(Day)).ToList(); // Initialise the internal array of tiles Tiles = new TimetableTile[Frame.Rooms.Count, Frame.Periods.Count]; for (int y = 0; y < Frame.Rooms.Count; y++) { for (int x = 0; x < Frame.Periods.Count; x++) { // Get the booking (or null) for this combination of room and timeslot Booking Current = RelevantBookings.Where(b => b.TimeSlot == Frame.Periods[x] && b.Rooms.Contains(Frame.Rooms[y])).SingleOrDefault(); // Create the timetable tile Tiles[y, x] = new TimetableTile(Current, Frame.Periods[x], Frame.Rooms[y], CurrentUser); // Layout Container.Children.Add(Tiles[y, x]); Tiles[y, x].SetValue(Grid.RowProperty, y + 1); Tiles[y, x].SetValue(Grid.ColumnProperty, x + 1); // Hook up the tile clicked handler Tiles[y, x].MouseLeftButtonDown += (o, e) => TileClicked((TimetableTile)o); } } }