从分配有 ControlTemplate 的 UWP 控件实例访问元素
Posted
技术标签:
【中文标题】从分配有 ControlTemplate 的 UWP 控件实例访问元素【英文标题】:Access an element from UWP control instance that has a ControlTemplate assigned to it 【发布时间】:2022-01-07 14:28:05 【问题描述】:我在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。
【问题讨论】:
你到底想做什么?当一个CalendarView
对象被渲染时,它会调用CalendarViewDayItemChanging
数百次。
@RoyLi-MSFT 当发生任何CalendarViewDayItemChanging
调用时,我想访问该事件调用的 DayItem 对象,并且我想访问此 DayItem 具有的特定网格对象,网格包含在我定义的控件模板中,由于 DayItem 的控件使用这个控件模板进行渲染,所以必须有访问它的方法。然后,我想根据该特定日期项目的其他一些信息将项目添加到此网格中。
【参考方案1】:
试试这个:
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;
【讨论】:
正是我需要的。谢谢。所以基本上我不能直接通过实例在任何地方访问元素,而是我需要将实例发送到 .NET DOM 处理器并在那里找到元素。以上是关于从分配有 ControlTemplate 的 UWP 控件实例访问元素的主要内容,如果未能解决你的问题,请参考以下文章
如何从代码隐藏中访问UserControl中样式的Setter中ControlTemplate中定义的Control实例?