簡體   English   中英

Winrt Hub節中的參考控件

[英]Reference control in Winrt Hubsection

我想獲得對WinRt集線器控件第一部分中的MediaElement的引用。 有人會認為這是微不足道的,但到目前為止,它已經是完整的PITA。

我用Google搜索了問題,發現:

如何訪問XAML DataTemplate中的控件?

如何訪問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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM