WPF – Paramétrage de droits d’accès à différents éléments d’IHM

by Sébastien Tessier 19. janvier 2011 19:49

Ce post donne un aperçu d’un mécanisme très intéressant de WPF. Il s’agit des DependencyProperty. Cela permet d’attacher une propriété à n’importe quel élément visuel. En fait, cela est plus général que les éléments visuels puisqu’il s’agit de tout objet dérivant de DependencyObject et les éléments visuels en dérivent tous.

Le but de ce post est de pouvoir paramétrer facilement l’accès aux éléments visuels de l’application.

Création de l’énumération

Tout d’abord, on crée l’énumération indiquant les différents niveaux d’accès pour l’application.

[Flags]
public enum AuthorizationLevel
{
    None = 0,
    Guest = 1,
    LoggedUser = 2,
    Administrator = 4,
    AllFromGuest = Guest | LoggedUser | Administrator,
    AllFromLoggedUser = LoggedUser | Administrator
}

Il faut noter 2 choses importantes :

  • l’attribut [Flags] qui permet de réaliser des combinaisons sur les 3 niveaux d’accès (Guest, LoggedUser et Administrator)
  • les 2 valeurs prédéfinies (AllFromGuest et AllFromLoggedUser) qui permettent d’indiquer un niveau d’accès pour plusieurs utilisateurs. 

Création de la propriété de dépendance

Il faut créer la propriété de dépendance “Level” de type AuthorizationLevel. On a besoin d’un Get, d’un Set et du callback déclenché lors du changement de valeur de cette propriété pour un élément visuel donné.

public static AuthorizationLevel GetLevel(DependencyObject obj)
{
    return (AuthorizationLevel)obj.GetValue(LevelProperty);
}

public static void SetLevel(DependencyObject obj, AuthorizationLevel value)
{
    obj.SetValue(LevelProperty, value);
}

public static readonly DependencyProperty LevelProperty =
    DependencyProperty.RegisterAttached("Level", 
        typeof(AuthorizationLevel), typeof(ConfigAuthorizationHelper),
        new UIPropertyMetadata(AuthorizationLevel.None, LevelChangedCallBack));

private static void LevelChangedCallBack(DependencyObject obj, 
    DependencyPropertyChangedEventArgs e)
{
    ChangeUIElementVisibility(obj as UIElement);
}

Maintenant, chaque élément visuel peut avoir une nouvelle propriété appelée Level.
Dans l’exemple suivant, la classe contenant la propriété statique Level s’appelle AuthorizationHelper et l’alias XAML du namespace de cette classe est tools. Pour afficher une grille uniquement pour les utilisateurs connectés (tous sauf Guest), on utilise le code XAML suivant.

<Grid tools:AuthorizationHelper.Level="AllFromLoggedUser">

Ajout de la logique de mise à jour du visuel

Dans la classe AuthorizationHelper, il manque la logique de mise à jour des éléments visuels ayant la propriété Level. Cette logique se trouve dans le code suivant :

static List<UIElement> _allAttachedUIElements = new List<UIElement>();
static AuthorizationLevel _currentUser = AuthorizationLevel.None;
public static AuthorizationLevel CurrentUser
{
    get { return _currentUser; }
    set
    {
        if (_currentUser != value)
        {
            _currentUser = value;
            foreach (var currentUIElement in _allAttachedUIElements)
                ChangeUIElementDisplay(currentUIElement);
        }
    }
}

static void ChangeUIElementDisplay(UIElement attachedUIElement)
{
    if (attachedUIElement != null)
    {
        if (!_allAttachedUIElements.Contains(attachedUIElement))
            _allAttachedUIElements.Add(attachedUIElement);

        bool userHasCorrectRights = ((_currentUser != None) 
            && ((GetLevel(attachedUIElement) & _currentUser) > 0));
        attachedUIElement.Dispatcher.Invoke(new Action(delegate
            { attachedUIElement.Visibility = userHasCorrectRights 
                  ? Visibility.Visible : Visibility.Hidden; }));
    }
}

Il ne reste plus qu’à mettre à jour “CurrentUser” à chaque changement d’utilisateur et l’interface sera mise à jour automatiquement. “CurrentUser” ne pourra être qu’une des valeurs suivantes : Guest, LoggedUser ou Administrator.

Tags: , ,

Développement

Neos-SDI  Neos-SDI