从分配有 ControlTemplate 的 UWP 控件实例访问元素

Access an element from UWP control instance that has a ControlTemplate assigned to it

我里面有下面的代码MainPage.xaml:

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

只是用于创建包含一些 CalendarView 实例的网格控件的原始标记。\

然后在 MainPage.xaml.cs 我生成了几个日历:

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){...}

    }
}

然而,这些日历的内部内容覆盖了 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>

每个日历控件实例都包含多个 CalendarViewDayItem 控件。 这些 CalendarViewDayItem 控件中的每一个都将使用上面的模板呈现其内容。

问题是:如何访问实例特定的网格元素(此处名称为 itemgrid)?

在一个理想的世界里,我会想象这样的事情:

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

我也知道只有当实例被充分构造时,这种访问才有效。 此外,也许一些实例绑定巫术可以工作。 这是一个类似于 How do I access an element of a control template from within code-behind 的问题 但我们这里是 UWP。

试试这个:

     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;
    }