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)
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();
}
}
<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.