![](/img/trans.png)
[英]How to access any control inside Hubsection Datatemplate in Windows 8.1 store
[英]Reference control in Winrt Hubsection
我想獲得對WinRt集線器控件第一部分中的MediaElement的引用。 有人會認為這是微不足道的,但到目前為止,它已經是完整的PITA。
我用Google搜索了問題,發現:
如何訪問Windows 8.1存儲區中Hubsection Datatemplate內部的任何控件
但是提供的代碼不起作用。
我的(相關)Xaml如下:
<Hub x:Name="MediaHub">
<Hub.Header>
<!-- Back button and page title -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button x:Name="backButton" Margin="-1,-1,39,0" Command="{Binding NavigationHelper.GoBackCommand, ElementName=pageRoot}"
Style="{StaticResource NavigationBackButtonNormalStyle}"
VerticalAlignment="Top"
AutomationProperties.Name="Back"
AutomationProperties.AutomationId="BackButton"
AutomationProperties.ItemType="Navigation Button"/>
<TextBlock x:Name="pageTitle" Text="{StaticResource AppName}" Style="{StaticResource HeaderTextBlockStyle}" Grid.Column="1"
IsHitTestVisible="false" TextWrapping="NoWrap" VerticalAlignment="Top"/>
</Grid>
</Hub.Header>
<HubSection Width="780" Margin="0,0,80,0">
<HubSection.Background>
<ImageBrush Stretch="UniformToFill" />
</HubSection.Background>
<DataTemplate>
<Grid Margin="15">
<Grid.RowDefinitions>
<RowDefinition Height="500"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<MediaElement x:Name="videoElement1" AreTransportControlsEnabled="True"/>
</Grid>
</DataTemplate>
</HubSection>
如下實現的findname建議返回null:
private void navigationHelper_LoadState(object sender, LoadStateEventArgs e)
{
this.videoElement = this.MediaHub.Sections[0].FindName("videoElement1") as MediaElement;
if (this.videoElement != null)
{
this.videoElement.MediaOpened += VideoElementMediaOpened;
this.videoElement.MediaFailed += VideoElementMediaFailed;
this.videoElement.MarkerReached += VideoElementMarkerReached;
}
}
並且VisualTree建議也返回null。
private void navigationHelper_LoadState(object sender, LoadStateEventArgs e)
{
this.videoElement = this.FindChildControl<MediaElement>(this, "videoElement1") as MediaElement;
if (this.videoElement != null)
{
this.videoElement.MediaOpened += VideoElementMediaOpened;
this.videoElement.MediaFailed += VideoElementMediaFailed;
this.videoElement.MarkerReached += VideoElementMarkerReached;
}
}
private DependencyObject FindChildControl<T>(DependencyObject control, string ctrlName)
{
int childNumber = VisualTreeHelper.GetChildrenCount(control);
for (int i = 0; i < childNumber; i++)
{
var child = VisualTreeHelper.GetChild(control, i);
var fe = child as FrameworkElement;
// Not a framework element or is null
if (fe == null) return null;
if (child is T && fe.Name == ctrlName)
{
// Found the control so return
return child;
}
else
{
// Not found it - search children
DependencyObject nextLevel = FindChildControl<T>(child, ctrlName);
if (nextLevel != null)
return nextLevel;
}
}
return null;
}
在這種情況下,找到了MediaHub,但是當使用MediaHub作為“控件”參數遞歸輸入功能FindChildControl時,
int childNumber = VisualTreeHelper.GetChildrenCount(control);
返回計數為0的值,因此它返回並向初始調用冒泡為null。 盡管如果我設置了一個斷點,我可以看到根據Xaml的HubSections count=4
。 (定義的部分比我輸入的要多,為簡潔起見,省略了這些部分)。
經過反思,似乎我被迫使用基於Xaml的樣式,例如:
<MediaElement x:Name="videoElement1" AreTransportControlsEnabled="True"
MediaOpened="VideoElement1_OnMediaOpened"
MediaFailed="VideoElement1_OnMediaFailed"
MarkerReached="VideoElement1_OnMarkerReached"
Source="{Binding SomeViewModelProperty}" />
我的問題是,我經常遇到以下問題:使用Source= new Uri("xyz")
靜默失敗,但是在同一源文件的代碼中使用myMediaElement.SetSource(stream, file.ContentType)="xyz"
可以正常工作100 % 的時間。 因此,我想在代碼中設置此源,因此需要參考。
因此,我不想將此Xaml選項用作我的問題的答案,而是希望如何動態訪問給定Hub的HubSection中的控件。 在這一點上,我也想了解一下。
編輯:
根據Dani的回答,我嘗試安裝WinRt工具包並運行以下代碼,但這也返回null。
private void navigationHelper_LoadState(object sender, LoadStateEventArgs e) {
var m = this.MediaHub.GetDescendantsOfType<MediaElement>().FirstOrDefault();
}
編輯2:
好的,基本上所有這些都可以歸結為Page生命周期,雖然我還沒有讀太多,但是需要在Hub的Loaded事件中同時運行Danis代碼和我的原始代碼。 這樣做,所有示例代碼塊都可以工作:
public HubPage1()
{
this.InitializeComponent();
this.navigationHelper = new NavigationHelper(this);
this.navigationHelper.LoadState += navigationHelper_LoadState;
this.MediaHub.Loaded += MediaHub_Loaded;
}
void MediaHub_Loaded(object sender, RoutedEventArgs e)
{
var m = this.MediaHub.GetDescendantsOfType<MediaElement>().FirstOrDefault();
this.videoElement =
this.FindChildControl<MediaElement>(this.MediaHub, "videoElement1") as
MediaElement;
}
就像WebForms一樣。 ;)
這是我的方法:
<Hub>
<HubSection>
<DataTemplate>
<Button Loaded="MyButton_OnLoad" />
</DataTemplate>
</HubSection>
</Hub>
然后這個:
private Button _MyButton = default(Button);
private void MyButton_OnLoad(object sender, RoutedEventArgs e)
{
_MyButton = sender as Button;
}
然后這樣:
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
this._MyButton.Visibility = Visibility.Visible;
}
這比通過VisualTree更好嗎? 也許。 輕一點
祝你好運!
我已經嘗試過使用WinRT XAML Toolkit中的VisualTreeHelperExtensions
類。
在那里您可以調用this.MediaHub.GetDescendantsOfType<MediaElement>();
然后您將獲得videoElement1。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.