Gestion de CommandBar multiples

En Universal App la déclaration d’une barre de commande s’effectue par le biais du contrôle CommandBar.
En XAML la déclaration du contrôle CommandBar est très simple (ici, dans la barre du bas) :

<Page.BottomAppBar>
    <CommandBar Background="#f0f0f0" Foreground="#606060">
        <AppBarButton Icon="Add" Label="Add"></AppBarButton>
        <AppBarButton Icon="Delete" Label="Delete"></AppBarButton>
        <AppBarButton Icon="ReShare" Label="Share"></AppBarButton>
        <AppBarButton Icon="List" Label="Manage"></AppBarButton>
    </CommandBar>
</Page.BottomAppBar>

CommandBar

Mais voila, lorsque je veux gérer plusieurs CommandBar dans la même page comment faire ?

Les ressources

La première chose à laquelle on pense c’est bien évidemment de positionner les CommandBar dans les ressources; celles de la page par exemple.
Ainsi il sera facile de choisir la CommmandBar à affecter à la BottomAppBar.
Peine perdue ! Au lancement de l’application, une exception sera levée :

CommandBars can only be set in Page.BottomAppBar.

Dommage, c’était la solution la plus élégante pour conserver la facilité d’écriture qu’offre XAML.

Par le code

On peut passer par l’écriture complète de la CommandBar via le code.
Oui cela marche très bien, mais ma motivation du moment m’empêche d’écrire une ligne de code à ce sujet.
D’autant plus qu’une autre solution beaucoup plus élégante existe 😉

On revient aux ressources

La CommandBar ne peut être gérée directement dans les ressources.
Soit ! Mais dans un autre contrôle cela ne semble pas lui poser de problème.

En créant un petit contrôle « CommandBarResource » chargé d’accueillir la CommandBar dans ses propriétés on remplie toutes les conditions nécessaires pour qu’il puisse être positionné dans les ressources.

Ainsi le code du contrôle CommandBarResource est un ContentControl qui ne contient qu’une propriété de type CommandBar:

using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Markup;

namespace SamuelBlanchard.Helpers
{
    [ContentProperty(Name="CommandBar")]
    public class CommandBarResource : ContentControl
    {
        public CommandBar CommandBar
        {
            get { return (CommandBar)GetValue(CommandBarProperty); }
            set { SetValue(CommandBarProperty, value); }
        }

        public static readonly DependencyProperty CommandBarProperty =
            DependencyProperty.Register("CommandBar", typeof(CommandBar), typeof(CommandBarResource), new PropertyMetadata(null));
    }
}

Son utilisation dans XAML reste très simple :

    <Page.Resources>        
        <sb:CommandBarResource x:Name="Bar1">
            <CommandBar Background="#f0f0f0" Foreground="#606060">
                <AppBarButton Icon="Add" Label="Add"></AppBarButton>
                <AppBarButton Icon="Delete" Label="Delete"></AppBarButton>
                <AppBarButton Icon="ReShare" Label="Share"></AppBarButton>
                <AppBarButton Icon="List" Label="Manage"></AppBarButton>
            </CommandBar>
        </sb:CommandBarResource>
        
        <sb:CommandBarResource x:Name="Bar2">
            <CommandBar Background="#f0f0f0" Foreground="#606060">
                <AppBarButton Icon="Add" Label="Add"></AppBarButton>
            </CommandBar>
        </sb:CommandBarResource>
    </Page.Resources>

Coté C# on aura plus qu’a choisir la barre que l’on souhaite afficher :

this.BottomAppBar = this.Bar1.CommandBar
...
this.BottomAppBar = this.Bar2.CommandBar

Conclusion

Difficile de comprendre pourquoi la CommandBar, qui est pourtant un contrôle XAML, n’est pas accessible directement depuis les Ressources de la page.
Mais tant qu’un hack reste possible on arrête de bouder et on retourne coder dans la joie et la bonne humeur !

Toi petit fainéant du code tu trouveras le source du contrôle ici.

leave your comment