Role based View XAML - xaml

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 UserControls 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 }/>

Related

selenium Page factory handle different elements for same page for different users

I have a simple question. I 'm sure many of us might have got into the same situation. I am using page object pattern. Below are the steps i do along the navigation.
Login to my application as one type of user.
Click some link to go form page.
On form page , fills the fields and submit
Logout
On 3) the form object page shows some different input fields depending on the type of the user, which i need to interact with. So how do i deal it within the same page object. Has anybody got into the same situation and have found some decent way of doing this ?
I know it a simple automation script not a Java project where we should be using all oops concepts but still I would go with the following:
Create a parent page class containing the common WebElements and methods.
Create child classes with elements and methods specific to that customer.
In the test, pass a parameter which specifies the type of customer and call the appropriate child class.
If you don't want any of this inheritance stuff, you can also try the following.
Create a page class with elements for all types of customers.
Create generic methods which can take a parameter customerType and perform operations like if customerType==1 do these operations else do these.
Another solution which popped up in my mind, assuming that all fields for a particular customer are mandatory, is as follows.
Create a common class for all elements.
Create a generic method in the page class which follows the condition, if this element is present then enter value.
If you understand the concept of Page object model then this questions will be more clear to you. Yes, inheritance is a big factor here. I suggest you read through this to see how a real page object model should work. And, solution of #3 question is as simple as UI mapping. Something like
#FindBy(how = How.NAME, using = "q")
private WebElement searchBox;
for each elements or similar implementation.
For a complete page object you should map all the elements not depending on the users. The reason being, every time you call that class it will be instantiated and all the mapped elements as well. There is no need of dynamically load the elements If any elements are not used or hidden on the page those will be available and you will not be using them anyway

Create and use global view in C# WP8 XAML

I was trying to digg something on this topic before, but have no luck. What I'm trying to achieve is pretty simple, but seems to be hard to achieve :-)
I have a WP8 app (C# XAML) and I need to implement global messages (something like toasts) which could be displayed across whole application no matter of current navigation processes. Such toast message(s) should be displayed even while user is navigating between pages. To use the built in toasts is not a way (in case some other solution exists) since I'm possibly in need to have more than one message displayed at the same time (each one is independent of another) and should disappear after specified period of time.
So, my question is. Is there any way how to implement and use some kind of global view instance which sits above all pages and can be called from any page?
All I found until now is the possible ability to use PhoneApplicationFrame, but I would like rather avoid that if possible. I'm still unsure if this is even the way it can be done, but I suppose so. Do you have any alternatives or assurance this is possible and only way to achieve this goal?
Thank you all for your time and answers.
You can have UerControl for the Functionality you are looking for. It is Control that has its own Seprate Xaml and cs file. You can call it from any page into your Project. UserControl provides the base class for defining a new control that encapsulates related existing controls and provides its own logic. You have a XAML file and C# class file for a user control. The class file extends the UserControl class and adds additional behaviours and properties. The XAML file encapsulates the composing controls, the styles, the templates, animations and whatever necessary to form the UI. Since it is a just composition, it is really easy to create. for more Reference you can go here Why and how to create a User Control in Windows Phone
I have ended up rolling my own custom navigation using a single master page. As such any global controls are instantiated once at startup. Navigations are called from my viewmodels and result in usercontrols being removed and added to the visual tree as necessary (using transition animations to give the impression of page navigation) This works but im not sure whether it is best practice and would appreciate some opinions and comments on this. Certainly it solves the problem of global views described.

ASP.NET MVC Set texts in the View or in the Controller

What is the best practice in MVC (for testing, SOC and scaffolding) for setting texts (for exemple page title, h1,h2..)
Is it better to do it in the controlle, fill a viewmodel and send it to the view
or directly typing texts in the view?
Also I will propably use ressouces files for global texts (like button text, menu texts) and local ressouces for view specific texts.
The view is merely to present the output to the user. Depending on your requirement you can either:
1) Type the text in the view directly <h2>Hello World</h2> (for static content that will not change)
The latter two options are for ideal for dynamic content, where the content could be received from a database or some additional input.
2) Use the ViewBag to pass information to the view (in which case you would set it in the controller ie. ViewBag.HelloWorld = "Hello World" : <h2>#ViewBag.HelloWorld</h2>
3) Use a model to pass the information to your view. This should be your preferred option where possible. In your specific case you could use the controller to retrieve the content from your global resources, bind it to the model and pass it to the view.
The logic on where to get the data should come from the controller and the View's function should be to merely display it.
I recommend binding properties on the viewModel to the UI.
This is not only more testable, but it's also more flexible. It makes it easier to implement features like mult language support etc.
I recommend avoiding hard coding text in the markup if you can

How to link the View and the ViewModel and where to create them

I have written a phone app using an MVVM framework. It came together okay - every page (view) on the phone has its own ViewModel and code within each ViewModel went away to the dataservice and retrieved appropriate data.
So I had a page showing an Agenda of upcoming items and its ViewModel retrieved a collection of events and within the XAML I bound a Listbox to this collection.
Similarly I had another page showing a OneOff Events and again, within its VM I called the data service to get a collection of data back and that was bound to a listbox within its view.
Not sure how good an implementation of MVVM this is, but, I ended up moving to a different database - and it was very easy to implement another dataservice without touching anything else and it all worked great.
Ok - so now I am looking to rework this app into a Windows Store app. I now have a main page that will show a combination of data that on the phone was shown on individual pages.
Hypothetically, assume that the Agenda items and One Off Events mentioned above are now appearing on the same main page (so much more room to show stuff)
Just struggling with what this means for ViewModel(s). If the MainPage can only work with one ViewModel, do I end up with one huge ViewModel that includes all the functionality that was in multiple VM's before.
Or should the Main ViewModel have within it collections of ViewModels. From looking around this seems to be the way it could be done, but, if so where are the ViewModels created?
It seems quite a fundamental shift from what I have done previously.
Yes, you can set different ViewModels as the binding context for different parts of your page. You can use the Locator pattern (one locator object with ViewModel properties) or Dependency Injection to keep the construction of things manageable.
Great sample code and slides by Gill Cleeren that discuss and show how the Contoso Cookbook sample application can be set up alternatively using MVVM and a ViewModelLocator class can be found here. The talk itself is on channel 9.
From these slides:
Data binding is the glue but...
A view needs to “find” its ViewModel
ViewModel is the DataContext
Can be static or dynamic
Static: View creates ViewModel and sets it as DataContext
Dynamic: at runtime, View selects its ViewModel or vice-versa
2 options:
View-First: ViewModel gets created because View is created
ViewModel-First: ViewModel is created and View gets selected

ExtJS 4 MVC multiple instances of views and sub/child controller difficulties

I have encountered a problem with the MVC pattern in ExtJS 4. At least, I think I have. Having approached multiple people with this question, and having posted numerous times in the Sencha forums, I am now turning to a broader audience in hopes of getting either a light bulb or a confirmation.
Problem
Your application has the ability to open many different views, some of which themselves are mini-applications. Additionally, a user may wish to have multiple concurrent copies of a view open.
This application is a single-page client-side Javascript application.
The ExtJS 4 MVC model expects you to define all of your controllers in your Application class. These controllers are then initialized when the Application loads. Controllers keep track of views, models and stores.
When you initialize controller A multiple times, say to create more than one copy of a view, you end up with two views that reference the same data stores, and functionally send duplicate events to the Application event bus.
I have refactored my application by adding new prototype methods to Component and Controller to allow for both a) sub controllers (some of my controllers were getting pretty huge) and b) defining stores specifically for the view they work with. The models can still be defined on the controller, just for ease of use by handlers if you need to do something like grab a record from the server.
Question
My understanding of MVC would lead me to believe that models more directly relate to the View than then Controller. I asssssume that ExtJS 4 decides to attach stores (which I think can be seen as wrappers to a more classic model) to Controllers for purposes of encouraging re-use of loaded data, and to optimize away from having many copies of the same class instantiated. It seems to me, however, that one cannot do this if one intends to have many instances of a view available to the user. To my thinking, having many instances is an important option in an OO framework, hence why I have bucked the trend and implemented prototypes on some of the Ext base classes. (Thank you Ext.implement!).
Is there any way to have multiple concurrent instances of a view with different data loaded into them using the out of the box MVC classes and making uses of the provided setters, getters, etc?
I was faced with a similar problem:
Consider a tabpanel for a CRM type application which opens new instances of a view for each client. And say that tab view contains 3 or 4 row-editing gridpanels for interacting with different collections of data relating to that client.
The solution I came up with was based on this from the Sencha forums. In a nut shell, almost all events that are dispatched from a view contain a reference to the view itself. The handlers in my controller's control function all use these to get a reference to the correct view instance.
For dealing with the multiple instances of the same store needed for this, I took this to heart from that post:
For the Store instance on the view or a global one... depends on the
needs. If you are going to use globally then make it global. If you
only are going to need it on the view then put it on the view. MVC is
not a law, you can change it to fit your needs. Technically the
Controller part of MVC is suppose to be the middle man between the
View and Model parts but sometimes that's just not needed. I create
the Store in the view 95% of the time. I'll give you an example...
If you have a Store for products, you probably only need to reference
that Store in your Grid. That usually isn't needed for other parts of
the application. However, if you have a Store to load countries, I
often need it globally so I only have to load it once and can then
set/use that Store in several views.
So I just created the needed store's that relate to a view instance specifically, inside the view's initComponent method. The application did have a few global stores that I created as store classes following the MVC recommendations. It worked out nicely to encapsulate the view instance stores inside the view. Then I only needed one instance of the controller.
To answer your question specifically, currently, there is no ExtJS official recommendation or config for dealing with multiple instances of the same view that use the same store constructor. I have spent some time looking for something like that and the best I have found was this recommendation from one of their forum moderators.
I don't think you ever need more than 1 instance of a controller, regardless of how many views/models you have. See functional example here:
http://whatisextjs.com/extjs-4-extension/fieldset-w-dynamic-controls-7
This can be done, reasonably easily. You need to follow a few rules:
load your controllers at app startup. Don't unload them. Don't worry about the memory or time, it's pretty small even for hundreds of controllers, as long as you minimize and concatenate your js.
Never use the refs or views properties of a controller. You are going to use one instance of a controller, but multiple instances of views, so you never want a reference to a view.
only use event listeners in controllers. You are only going to listen to events on your views. You can always get a (temporary) reference to a view in the event handler via the "cmp" parameter in the handler.
To "launch" a view, create it and add it to another view. To destroy it, destroy it. You don't use a controller to launch a view. You can use the afterrender and beforedestroy events in the controller to add logic.
In ExtJS' MVC the controller is a Singleton for you view. I like how DeftJS thinks about MVC. Each instance of a view has an own instance of a controller. In this way you can put all "controlling rules" in a controller for a particular part of your view, and this will be instantiated only when the view opens.
I did not have any experience how I could use multiple Defts JS apps in the same project.
Of course. What led you to believe otherwise?
Here is an example of creating a custom View which extends from a Window component. You can run this method many times from the same controller and each time you will get a new instance of a View.
"this" refers to a controller that code runs in:
this.getRequestModel().load(requestID,{ //load from server (async)
success: function(record, operation) {
var view = Ext.widget('requestEdit',{
title: 'MyRequest '+requestID
});
var form = view.down('form');
form.loadRecord(record);
}
});
How do you create your views? I see no reason why you cannot pass a different store or config data to every object. Some code samples would help for what exactly you are doing. For example, we have a similar sounding application, and everything is done with extensions. So, if we need a grid, we run
Ext.define('MyApp.grids.something',{
extends:'Ext.grid.panel'
//...
These classes are predefined. Then, when a controller or view is loading this grid, they are using
var grid=Ext.create('MyApp.grids.something',{id:'unique',store:mystore});
As you can see, we can pass in different config options to the same grid each time it is created. We can treat this exactly as you would treat
Ext.create('Ext.grid.Panel');
Except of course that we make some options predefined, and some non-override-able, and so on.
Hope this helped.
Check out this post. The idea there is to take some configuration (like store and itemId) from view config and put it into the viewport config:
// .../app/view/Viewport.js
Ext.define('MyApp.view.Viewport', {
// ...
items: [
// ...
{ xtype: 'testview', store: 'Store1', itemId: 'instance1' },
{ xtype: 'testview', store: 'Store2', itemId: 'instance2' }
]
});
The problem with store will be solved, obviously. Different itemIds will enable you to handle events properly.