views:

1179

answers:

2

I am using C#'s Identity and Principal objects for role based security, and I am at the step of modifing 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 Identity.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)

Thanks!

+1  A: 
<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.

Will Eddins
Thanks for the reply. The roles I am using update only when closing and re-opening the application, so NotifyPropertyChange is not critical. I thought about this method, but was hoping that something more direct existed - sorta like the role attribute syntax one can use on methods.
Thies
+6  A: 

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();
    }
}
Sergej Andrejev
Ahh, this is very much to my liking. With this in the XAML it should be straight forward to see the access that is required to see the different elements in the GUI. Thank you.
Thies
You are welcome
Sergej Andrejev
fellow code swipers, you may need to add "return" before "new NotImplementedException();"
SteveCav
:) Or throw....
Sergej Andrejev