I am developing a WinRT app which has many user roles. The View of many pages in my app change based on the Userrole
For eg. I have a Student role and a Professor role. When the Student logs in he will see personal-info, performance chart, todos and badges received and when a professor logs in she will see her personal-info, todos and feedback received
How do I only show the components which are necessary?
Is binding Grid.Visibility a good way of doing this or is there any better way?
Update:
By doing it the way suggested by @Ahmed(answers below) I will be loading all the controls in the design and only change the visibility of it. My page will still be heavy.
Is there anyway where I can load only the controls which I wish to see
There are certainly many ways to compose your UI.
- You can use
Visibility
as suggested to show or hide various parts of your UI.
- You can use
VisualStateManager
to show or hide various views or even change the templates.
- You can use an
ItemsControl
with ItemTemplateSelector
to display different items based on the input collection from the view model - e.g. for a student the ItemsSource
of the ItemsControl
would be bound to a collection of view models for personal-info, performance chart, todos and badges received and for a professor you would get view models for personal-info, todos and feedback received. The ItemTemplateSelector
would provide a different view of these specific items.
- You could also use an
ItemsControl
with ItemTemplateSelector
to display different views of same view models depending on the user role that you would pass to the selector.
- You could use a
ContentControl
with a custom ContentTemplateSelector
that would provide a different view based on the user role information provided in the view model bound to the Content
property.
- You can write some code behind to show/hide/add/remove UI components based on the user role.
- You can encapsulate various views (badges, personal info, feedback, etc.) in separate
UserControl
s per view and use any of the above techniques to show/hide specific views.
- You can design a different page for a different user role and depending on the role - navigate to a specific page.
- Finally you can create separate apps for different user roles.
All of the above would strongly benefit from using the MVVM pattern. The choice of a technique or rather combination of techniques would depend on what information you want displayed, how it's supposed to be laid out, how maintainable you want it to be vs. how quick to initially develop, how secure you want it to be and finally how much you know, are willing to learn or have time to do so.
If there are not too many roles - I would personally probably create a separate app for each role and reuse as much of the code as possible, though that would also depend on some other requirements - like the ability for two people to access the system from the same device. I wouldn't use the show/hide techniques at all since that still requires the UI to be loaded, use up memory etc. Most apps have some sort of a central hub/dashboard implemented as a GridView or some other layout and display shortened previews of the data/links to go to detailed views or full lists. This is where I would provide different data in the view model for different roles. Detail pages would likely not need as much customization since the data would look mostly the same for each role or be inaccessible to some roles at all. Depending on permissions of course some people might be allowed to edit or see more/less of the data. For such smaller differences you could use template selectors, provide different data from the view models and control edit button visibility using command bindings.
The answer might be pretty broad and vague since a lot here depends on your specific design and requirements.
you can make your own converter something like this, that will change visibility based on roles
public class RoleToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var user= value as User;
if(user!= null) {
return user.IsInRole((string)parameter) ? Visibility.Visible : Visibility.Collapsed;
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
And in your XAML you can use your converter to set control's visibility like this
<Control Visibility={Binding Path=CurrentUser, Converter={StaticResource RoleToVisibilityConverter}, ConverterParameter=Student }/>