Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to manipulate WPF GUI based on user roles

I am using .NET's IIdentity and IPrincipal objects for role based security, and I am at the step of modifying controls shown based on roles the current user has.

My question is what the recommended method is for enabling/disabling fields in a WPF window - showing/hiding fields dependent on IIdentity.IsInRole type calls.

Can this be done in XAML, or do I have to abstract this into code with what I think is a bit messy in the code behind;

this.txtUserName.IsReadOnly = !MyPrincipal.CurrentPrincipal.IsInRole("Administrator");
this.mnuCreateUser.Visibility = MyPrincipal.CurrentPrincipal.IsInRole("Administrator");
 ? Visibility.Hidden : Visibility.Visible;

(Note; my code checks roles when executing functions, what I am looking to do is modifying the GUI dependent on the roles, so users do not see/see readonly elements that they do not have access to)

like image 366
Thies Avatar asked Jun 19 '09 17:06

Thies


2 Answers

Although previous answer will work, to me it looks little ugly to detect visibility in logic objects. I would use converter for that...

<Control Visibility={Binding Path=CurrentPrincipal, Converter={StaticResource RoleToVisibilityConverter}, ConverterParameter=Administrator}/>

And then the converter itself

public class RoleToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var principal = value as Principal;
        if(principal != null) {
            return principal.IsInRole((string)parameter) ? Visibility.Visible : Visibility.Collapsed;
        }

        return null;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
         throw new NotImplementedException();
    }
}
like image 104
Sergej Andrejev Avatar answered Oct 21 '22 15:10

Sergej Andrejev


<Control Visibility={Binding ElementName=ThisWindow, Path=AdministratorVisibility, Mode=OneWay}/>

In your C# code:

public Visibility AdministratorVisibility
{
    get 
    { 
        MyPrincipal.CurrentPrincipal.IsInRole("Administrator") ? Visibility.Hidden : Visibility.Visible; 
    }
}

You can do the same thing for implementing something for IsReadOnly. If the user's role can change (I'm not sure how these user roles work), you can implement INotifyPropertyChanged and do NotifyPropertyChanged("AdministratorVisibility"), otherwise you could probably change the BindingMode to BindingMode.OneTime and skip implementing the notifications.

This probably isn't a whole lot better than what you're doing already, but it's probably as good as you're going to get.

like image 1
Will Eddins Avatar answered Oct 21 '22 14:10

Will Eddins