我正在开发 Win8.1 应用程序,主页使用 Hub。在每个 HubSection 中,我需要从代码访问不同的控件。 HubSection 的内容不是直接定义的,而是由 DataTemplate 定义的。因此,无法通过 x:Name 访问内容。以下情况是不可能的:
<Page ...>
<Grid>
...
<Hub ...>
<HubSection x:Name="ListSection">
<DataTemplate>
<local:MyListUserControl x:Name="ListControl"/>
</DataTemplate>
</HubSection>
<HubSection x:Name="ImageSection">
<DataTemplate>
<local:MyImageUserControl x:Name="ImageControl"/>
</DataTemplate>
</HubSection>
</Hub>
</Grid>
</Page>
void MainPage_Loaded(object sender, RoutedEventArgs e) {
// Not possible. Elements within DataTemplate cannot be accessed...
ListControl.DoSomething();
ImageControl.DoSomethingDifferent();
}
由于无法直接访问控件,我尝试遍历 VisualTree 来手动查找控件 - 正如类似问题的答案中所建议的:
MyListUserControl listControl;
MyImageUserControl imageControl;
void MainPage_Loaded(object sender, RoutedEventArgs e) {
FindControls(this);
if (listControl != null)
listControl.DoSomething();
if (imageControl != null)
imageControl.DoSomethingDifferent();
}
private void FindControls(DependencyObject parent) {
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++) {
DependencyObject child = VisualTreeHelper.GetChild(parent, i);
if (child is MyListUserControl) {
listControl = (child as MyListUserControl);
} else if (child is MyImageUserControl) {
imageControl= (child as MyImageUserControl);
}
if (listControl == null || imageControl == null)
FindControl(child);
else
break;
}
}
这也不起作用,只找到了 MyListUserControl。如果我记录子元素,VisualTree 看起来像这样:
...
13: Windows.UI.Xaml.Controls.Grid
14: Windows.UI.Xaml.Controls.ScrollContentPresenter
15: Windows.UI.Xaml.Controls.ItemsStackPanel
16: Windows.UI.Xaml.Controls.HubSection
17: Windows.UI.Xaml.Controls.Border
18: Windows.UI.Xaml.Controls.Grid
19: Windows.UI.Xaml.Shapes.Rectangle
19: Windows.UI.Xaml.Controls.Button
20: ...
19: Windows.UI.Xaml.Controls.ContentPresenter
20: MyListUserControl
ItemsStackPanel (15) 只有一个子项,即其中包含 MyListUserControl 的第一个 HubSection。未找到其他 HubSection。至少这是大多数时候发生的情况。也恰好找到了前三个部分。甚至有时所有部分都能找到。
因此,搜索方法或 XAML 没有任何问题。集线器似乎不会一次加载所有部分。那么,如何访问这些部分中的控件呢?