I had a Calendar Page in a UWP XAML project for WindowsPhone10 used to display trips a user had planned. The calendar showed these trips on a month by month basis so the user could see all trips for the selected month.

I created a UserControl for each day and within that day each trip is also a UserControl.

The trip UserControl has 2 buttons, a StartedDayHere button and an EndedDayHere button. I needed the day UserControl to know when these had been tapped.

To do this I create custom events and delegates so the day UserControl could hook into these on the button click events:

public delegate void StartedDayHereClickedEventHandler(object sender, EventArgs e);
public event StartedDayHereClickedEventHandler StartedDayHereClicked;
        
public delegate void EndedDayHereClickedEventHandler(object sender, EventArgs e);
public event EndedDayHereClickedEventHandler EndedDayHereClicked;

Then the button click event in the trip UserControl would trigger these events as appropriate (the Trip object is a member variable of the trip UserControl:

private void btnStartedDay_Click(object sender, RoutedEventArgs e)
{
    if (Trip.StartedDayHere)
    {
        return;//do nothing - only process when moving from off to on
    }
    else
    {
        StartedDayHereClicked(this, new SkyronEventArg() { TripId = Trip.Id });
    }
}

private void btnEndedDay_Click(object sender, RoutedEventArgs e)
{
    if (Trip.EndedDayHere)
    {
        return;//do nothing - only process when moving from off to on
    }
    else
    {
        EndedDayHereClicked(this, new SkyronEventArg() { TripId = Trip.Id });
    }
}

As you can see, I created a SkyronEventArg object so I could pass the trip ID, looking back, I don’t think this was required as the trip UserControl is sent as the “sender” in the event, so I could just cast sender to a trip UserControl and get the trip ID from the Trip property. Having said that, this is still a good way of sending additional data should you need to.

Then, in my day UserControl I would create the trip UserControls as necessary, hooking into the custom click events just created, and adding it to the StackPanel in the UI. This function is called during the initial page load and as the trip UserControl buttons are tapped:

private void CreateCalendarTripUserControls(int year, int month, int day, List tripsForDay)
{
    stackPanelMainContent.Children.Clear();

    Date = new DateTime(year, month, day);
    tbDate.Text = day.ToString();
    tbDay.Text = Date.DayOfWeek.ToString().Substring(0, 3).ToUpper();

    if (tripsForDay.Count > 0)
    {
        for (int i = 0; i < tripsForDay.Count; i++)
        {
            CalendarTripUserControl calendarTripUserControl = new CalendarTripUserControl(tripsForDay[i]);
            stackPanelMainContent.Children.Add(calendarTripUserControl);

            //hook into clicked events
            calendarTripUserControl.StartedDayHereClicked += (sender, eventargs) =>
            {
                int? newStartedDayHereTripId = (eventargs as SkyronEventArg).TripId;
                if (newStartedDayHereTripId.HasValue)
                {
                    ChangeStartedDayHereTrip(newStartedDayHereTripId.Value);
                }
            };

            calendarTripUserControl.EndedDayHereClicked += (sender, eventargs) =>
            {
                int? newEndedDayHereTripId = (eventargs as SkyronEventArg).TripId;
                if (newEndedDayHereTripId.HasValue)
                {
                    ChangeEndedDayHereTrip(newEndedDayHereTripId.Value);
                }
            };
        }
    }
    else
    {
        CalendarTripUserControl calendarTripUserControl = new CalendarTripUserControl(null);
        stackPanelMainContent.Children.Add(calendarTripUserControl);
    }

    stackPanelMainContent.UpdateLayout();
}

As you can see above, I ensure there is a Trip ID before proceeding. If there is one, I call the ChangeStartedDayHereTrip function passing the trip ID. This is where you would do whatever it is you need to do in the day UserControl when a button is clicked in one of the child trip UserControls. In my project I needed to save some changes to the database, re-order the trips and update the UI.

Here’s my full ChangeStartedDayHereTrip function:

private void ChangeStartedDayHereTrip(int newStartedDayHereTripId)
{
    //this trip should be set as the startedDayHere trip - all other trips on this date should have startedDayHere set to false
                
    List todaysTrips = new List();
    for (int j = 0; j < stackPanelMainContent.Children.Count; j++)
    {
        if (stackPanelMainContent.Children[j].GetType() == typeof(CalendarTripUserControl))
        {
            todaysTrips.Add((stackPanelMainContent.Children[j] as CalendarTripUserControl).Trip);
        }
    }

    //update the previous startedDayHere trip - there should onle ever be one - but handle more than one in case the TT web service changes the data.
    List previousStartedDayHereTrips = todaysTrips.Where(p => p.StartedDayHere == true).ToList();
    previousStartedDayHereTrips.ForEach(p => p.StartedDayHere = false);
    DatabaseHelper.UpdateTrips(previousStartedDayHereTrips);

    Trip newStartedDayHereTrip = todaysTrips.SingleOrDefault(p => p.Id == newStartedDayHereTripId);
    if (newStartedDayHereTrip == null)
    {
        return;//shouldn't happen but failsafe
    }
    else
    {
        newStartedDayHereTrip.StartedDayHere = true;
        DatabaseHelper.UpdateTrip(newStartedDayHereTrip);
    }

    //put the new startedDayHere trip at the start of the list
    todaysTrips.Remove(newStartedDayHereTrip);
    todaysTrips.Insert(0, newStartedDayHereTrip);

    //re-create UI list
    CreateCalendarTripUserControls(newStartedDayHereTrip.Date.Year, newStartedDayHereTrip.Date.Month, newStartedDayHereTrip.Date.Day, todaysTrips);            
}

There is also an equivalent ChangeEndedDayHereTrip function.