Loupe

[Windows8.1] Accéder aux contrôles d’un Hubsection en Windows 8.1

Le Hub est un des contrôles disponibles en XAML depuis Windows 8.1 . Malheureusement il peut s’avérer difficile d’accéder aux contrôles qu’il contient.

Nous allons expliquer les raisons de ce problème et comment y remédier.

 

Je ne vais pas détailler comment l’implémenter car cette page de la msdn est très claire : https://msdn.microsoft.com/fr-fr/library/windows/apps/bg182878.aspx#Hub

 

Pour revenir à notre problématique, il faut savoir qu’un Hub est composé de Hubsection et la particularité de ces Hubsections est dans la déclaration de leur contenu qui doit être déclaré via DataTemplates.

Voici un exemple de Hub :

<Hub Header="News">
    <HubSection Header="Latest" x:Name="MyHubSection">
        <DataTemplate>
            <GridView x:Name="MyGridView"/>
        </DataTemplate>
    </HubSection>
    …
</Hub>

 

Notre souci est sur la récupération des contrôles à l’intérieur d’un HubSection comme la GridView.

Comme le contenu n’est pas déclaré directement mais par template. Hors chaque datatemplate instancie son propre namespace de résolution des contrôles par leur nom. Il n’est donc pas possible d’accéder au contrôle directement en lui ajoutant un x:Name.

 

Et si le VisualTree était la solution

Une des solutions qui nous vient en tête est d’utiliser le VisualTree pour parcourir nos contrôles.

Malheureusement, le Hub principal ne charge pas tous les Hubsection directement car son panel sous jacent fait de la virtualisation. Nous pouvons donc récupérer un VisualTree incomplet si nous l’appelons trop tôt. Nous ne savons pas non plus quand tous les HubSection sont prêt pour appeler le VisualTree.

Cette solution n’est donc pas envisageable.

 

Laissons le contrôle se manifester lui-même

Une autre solution, bien plus simple est finalement de s’abonner à l’évènement OnLoaded de notre contrôle à suivre.

<GridView x:Name="MyGridView"
          Loaded="OnMyGridView_Loaded"/>

 

Dans notre code-behind, nous n’avons plus qu’à enregistrer le contrôle pour pouvoir le manipuler par la suite :

private void OnMyGridView_Loaded(object sender, RoutedEventArgs e)
{
    _myGridView = sender as GridView;
}

 

La solution la plus simple est souvent la meilleure !

Ces billets pourraient aussi vous intéresser

Vous nous direz ?!

Commentaires

comments powered by Disqus