0

I have the following code inside MainPage.xaml:

<Page ...>
   <VariableSizedWrapGrid Name="ContentGrid"/>
</Page>

Just a primitive markup to create a grid control that will contain some CalendarView instances.\

Then in MainPage.xaml.cs I generate a couple of calendars:

namespace App1 {

    public sealed partial class MainPage : Page {

        public MainPage() {
            this.InitializeComponent();
            for (int i = 1; i <= 12; i++)
            {
                CalendarView instance = new CalendarView();
                instance.CalendarViewDayItemChanging += myEvent;
                ContentGrid.Children.Add(instance);
            }
        }

        private void myEvent(CalendarView sender, CalendarViewDayItemChangingEventArgs args){...}

    }
}

These calendars however, have internal content that has overriden style which is defined in App.xaml

<Application ...>
    <Application.Resources>
        <ResourceDictionary>

            <Style x:Key="CalendarViewDayItemRevealStyle" TargetType="CalendarViewDayItem">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="CalendarViewDayItem">
                            <Grid x:Name="itemgrid" />
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>

            <Style TargetType="CalendarViewDayItem" BasedOn="{StaticResource CalendarViewDayItemRevealStyle}" />

        </ResourceDictionary>
    </Application.Resources>
</Application>

Every calendar control instance contains multiple CalendarViewDayItem controls. Each of these CalendarViewDayItem controls will be rendering its content with the template above.

The question is: How to access instance specific grid element (here with name itemgrid)?

In an ideal world I would imagine something like this:

private void myEvent(CalendarView sender, CalendarViewDayItemChangingEventArgs args){
    CalendarViewDayItem instance = args.Item;
    ControlTemplate instance_template = instance.Template;
    Grid g = (Grid)instance_template.getValue().getElementByName("itemgrid");
}

I also know that this access should work only when the instance is sufficiently constructed. Also, maybe some per-instance binding witchcraft could work. This is a similar question to How do I access an element of a control template from within code-behind but we are in UWP here.

Patrik Staron
  • 331
  • 1
  • 9
  • What do you want to do exactly? When a`CalendarView ` object is rendered, it will call the `CalendarViewDayItemChanging ` hundreds of times. – Roy Li - MSFT Dec 01 '21 at 07:14
  • @RoyLi-MSFT When any call of `CalendarViewDayItemChanging` occurs, I want to access the DayItem object of that event call and I would like to access the specific grid object that this DayItem has, the grid contained in the control template that I defined, as the control of DayItem uses this control template for rendering, so there must be a way to access it. I would then like to add items to this grid based on some other info of that particular day item. – Patrik Staron Dec 02 '21 at 22:04

1 Answers1

1

Try this:

     private void Instance_CalendarViewDayItemChanging(CalendarView sender, CalendarViewDayItemChangingEventArgs args)
    {
        CalendarViewDayItem item = args.Item;

        Grid grid = FindMyChildByName(item, "itemgrid") as Grid;
    }

public static DependencyObject FindMyChildByName(DependencyObject parant, string ControlName)
    {
        int count = VisualTreeHelper.GetChildrenCount(parant);

        for (int i = 0; i < count; i++)
        {
            var MyChild = VisualTreeHelper.GetChild(parant, i);
            if (MyChild is FrameworkElement && ((FrameworkElement)MyChild).Name == ControlName)
                return MyChild;

            var FindResult = FindMyChildByName(MyChild, ControlName);
            if (FindResult != null)
                return FindResult;
        }

        return null;
    }
Ax1le
  • 6,563
  • 2
  • 14
  • 61
  • Exactly what I needed. Thanks. So basically I cannot access the element anywhere through the instance directly, but rather I need to send the instance to a .NET DOM processor basically and find the element there. – Patrik Staron Dec 04 '21 at 12:30