In XAF applications, View settings are stored in Model Differences individually for each user. When the user changes the View (e. g., adds a column to a List View or groups View Items in a Detail View layout), these settings are saved in the user's Model Differences and applied to this View the next time it is displayed.
The built-in View Variants Module allows creating multiple predefined view settings using the Model Editor or in code and provides the end user with the capability to select a view variant at runtime.
Scenario
We want to provide the capability to save customized view settings as new view variants at runtime, share them, and allow any user having the corresponding permission to select a variant and apply these settings.
Solution
In this example, we use a persistent class to store view settings in the database and a view controller with actions to manage these settings (creating, applying and deleting). Each user can create his/her own view variants. Each view variant can be optionally marked as shared, so that other users can see and apply it to their views.
First, create the SettingsStore class with the following properties to store the View settings:
1. Xml - a string where serialized view settings are stored;
2. Name - the name of the View Variant;
3. OwnerId - an identifier of the user who created this Variant;
4. IsShared - specifies whether this Variant is shared with other users, or not;
5. ViewId - an identifier of the View for which this variant is created.
Then, create the ViewController with the following behavior:
1. There are Shared Model Settings available for each user, which cannot be edited by them.
2. Each user has his/her own default settings saved in the user's Model and used when there are no variants.
3. The SaveAsNewViewVariant action creates a new View Variant based on current view customizations. If this is the first Variant created for the view, two new Variants are created: a Variant that stores default settings (named "Default") and a Variant that stores customized view settings. If at least one Variant already exists, only the latter View Variant (with current customizations) is created. This variant becomes current.
4. The SelectViewVariant action makes the View Variant selected in the combo box current. This action is available when at least one variant exists. When the current View Variant is changed, customizations applied to the previous View Variant are lost. Only the "Default" View Variant customizations are saved in the Model when the current variant is changed.
5. The UpdateCurrentViewVariant action saves customizations to the currently selected View Variant.
6. The DeleteViewVariant action deletes the current View Variant. After deletion, the "Default" view variant becomes current and its settings are applied.
7. The UpdateDefaultViewVariant action saves customizations made to the current view in the "Default" Variant.
Actions provided by the ViewVariantsController controller may look as follows:
![]()
This example demonstrates the basic functionality, which you can expand or customize according to your requirements. For example, you can prevent certain users from deleting View Variants using the Security System facilities. Also, you can store the current Variant in the Model (see the Extend and Customize the Application Model in Code topic in our documentation) or in a property of the user object and apply it when the corresponding View is opened.
Note that the approach demonstrated by this example may be inappropriate or too complicated for certain use cases. So, we cannot guarantee that it will work in all possible scenarios. Should you face any issue using this solution or difficulty implementing it in your project, please submit a separate ticket and describe your scenario in detail. We will research this information to make the functionality better.
Question Comments
Added By:
Michael Bogaerts at:
8/24/2017 3:14:06 AM Modified it a little to match my EF project.
Works very wel for me except for deleting the variants.
The ObjectSpace of the CurrentLayoutItem is null in the
DeleteViewVariantAction_Execute
action I wil investigate this a bit further to figure out what is going wrong... Added By:
Michael Bogaerts at:
8/24/2017 4:01:27 AM this fixes it for me
[C#]
privatevoidDeleteViewVariantAction_Execute(objectsender,SimpleActionExecuteEventArgse){IObjectSpaceLinkcurrentLayoutItem=SelectViewVariantAction.SelectedItem.DataasIObjectSpaceLink;if(TryLoadViewVariantFromXML(defaultUserSettings)){IObjectSpaceos=currentLayoutItem.ObjectSpace;os.Delete(currentLayoutItem);os.CommitChanges();UpdateActions(null);}}
Added By:
Alex Gn (DevExpress) at:
8/24/2017 7:06:33 AM Hello Michael,
Thank you for the feedback. I have updated the sample.
Added By:
Zoltan Etelvari at:
8/25/2017 3:16:05 AM Hi DevExpress Team !
To share views between users is a COOL feature that I suggested about a year ago.
(thanks for the implementation).
Another idea :
To extend SettingStore class :
IsUpdated - specifies, where the user can updated another user's shared view,- I mean I make RO the view, but I share.
If IsUpdated = false , - view is read only,- user simply save the view with another name, and modify it. that's it.
So I think, this is a small modifying in code, and I think, with this features would be this solution perfect.
thanks
Zoltan
Added By:
Alex Gn (DevExpress) at:
8/25/2017 4:12:39 AM Hello Zoltan,
Thank you for your feedback. We will take this scenario into account. Currently, you can disable unwanted actions in the UpdateActionsActive method based on property values of a selected variant.
Added By:
Michael Bogaerts at:
8/25/2017 4:34:12 AM Hi Alex,
How far in details would like the feedback to go? should i report i there in the comments of do you prefer different tickets?Added By:
Alex Gn (DevExpress) at:
8/25/2017 5:30:07 AM Hello Michael,
Would you please describe the scenarios you'd expect to have in the sample and the problems you faced during the implementation. A new ticket would be more preferred.
Added By:
Lenny Sorey at:
10/2/2017 10:44:32 AM This is very close to what I need, but I have a question regarding the Application Model.
I am using the DB as the UserModelDifferenceStore, AND I am using a version of the SettingsStore class in this example.
What I'd like to be able to do is to prevent any user from updating the model for a list view (so that I have a universal default for that view). I'd also like to have any and all variants be diff'ed against that default view.
So now my question: How can I prevent users from storing changes to the model for a particular view in the UserModelDifferenceStore? I have created an extender for list views that allows me to get;set whether I am planning to use this custom view variants store, but the application model is getting saved in the database with the design changes, so that subsequent instances of the view are built with the DB settings instead of the "default" settings.
I guess I'm looking to trap the View.ModelSaving event and make sure the changes apply to the Settings store and NOT to the user's base Application Model. Is there another event I should be interested in, 'cause I can't that one to prevent the update.