从分配有 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;
}
我里面有下面的代码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;
}