我正在使用Win8.1应用程序,主页面使用Hub。在每个HubSection中,我需要从Code访问不同的控件。 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。如果我记录Child元素,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没有任何问题。 Hub似乎不会立即加载所有Sections。那么,我如何访问章节中的控件?
答案 0 :(得分:1)
您可以使用自己控件的Loaded事件,sender参数将是您正在寻找的控件。
<local:MyListUserControl x:Name="ListControl" Loaded="ListControl_Loaded"/>
然后在代码中:
private void ListControl_Loaded(object sender, RoutedEventArgs e)
{
listControl = (MyListUserControl)sender;
}
你也可以为你的ImageControl做同样的事情。