Search This Blog

Wednesday, March 29, 2017

Improving UX with Grid List Editors by disabling ALL unsupported operations for non-persistent columns in server modes (XAF v16.2.6) - YOUR FEEDBACK IS NEEDED!

In server modes, grid controls perform operations like sorting, grouping, filtering, etc. on the data store side to guarantee the best performance. Thus, columns bound to non-persistent properties (their values exist only in the client memory at runtime) cannot be used for such server-based operations and can cause exceptions (learn more...). Some of them can be detected only in the end application after navigating to a problematic grid at runtime.


With XAF 16.2.6, to prevent these situations, we have improved column creation logic in our Grid List Editors for Windows and the Web. In particular, we have disabled all server-based operations (sorting, filtering, grouping) for non-persistent properties in the ASP.NET WebForms ASPxGridListEditor and WinForms GridListEditor when DataAccessMode = Server or InstantFeedback. 

Technically, it means the following:
    1) The grid's Find Panel does not take non-persistent properties into account.
    2) The grid's Filter Editor does not display non-persistent properties in the properties tree.
    3) The grid's Auto Filter Row feature is not available for non-persistent columns.
    4) Grid column headers for non-persistent columns do not allow end-users to filter, sort, group.


See this video recorded from the WinForms version of our MainDemo:


Take special note that in XPO, calculated non-persistent properties defined using PersistentAliasAttribute or CalculatedAttribute can still be used without problems for server-based operations as previously. The only PersistentAlias attribute scenario, which may still not lead to disabled server-side operations, is when you have an aliased reference property and a grid column with a complex property path like:
YourPersistentAliasReferenceProperty.SomeNestedProperty1.SomeNestedPropertyN.
Such properties will be treated as regular non-persistent properties for now or you can disable our improvement using the feature toggle below.
For EF, calculated properties defined using CalculatedAttribute are still unsupported and treated as regular non-persistent properties mentioned above.

I do not need this behavior. How do I disable it?
With v16.2.7 (or, after installing this hot fix), you can set the PreventServerSideOperationsForNonPersistentMembers property of the DevExpress.ExpressApp.Editors > ColumnsListEditor  class to False in the overridden OnActivated method of a custom ViewController for a required ListView. Refer to the following example:

[C#]
using DevExpress.ExpressApp; using DevExpress.ExpressApp.Editors; namespace MainDemo.Module.Controllers { public class S31714_FeatureToggle : ViewController<ListView> { protected override void OnActivated() { base.OnActivated(); ColumnsListEditor columnsListEditor = View.Editor as ColumnsListEditor; if(columnsListEditor != null) { columnsListEditor.PreventServerSideOperationsForNonPersistentMembers = false; } } } }
[VB.NET]
Imports DevExpress.ExpressApp Imports DevExpress.ExpressApp.Editors Namespace MainDemo.Module.Controllers Public Class S31714_FeatureToggle Inherits ViewController(Of ListView) Protected Overrides Sub OnActivated() MyBase.OnActivated() Dim columnsListEditor As ColumnsListEditor = TryCast(View.Editor, ColumnsListEditor) If columnsListEditor IsNot Nothing Then columnsListEditor.PreventServerSideOperationsForNonPersistentMembers = False End If End Sub End Class End Namespace

Tuesday, March 28, 2017

Filtering - How to search objects within ListPropertyEditor or enabling the standard FullTextSearch Action for nested ListView

Just wanted to repost a nice tip from the old SC ticket, which I updated today:

By default, the standard FullTextSearch Action is mapped to the "FullTextSearch" category or Action Container that is physically present in the main, detail and lookup control templates. Historically, it is missing in the nested frame template, which is typically used for ListPropertyEditor, DetailPropertyEditor or DashboardViewItem, mainly not to overload their toolbar with a large text box.

If you still need full text search functionality in nested frame templates, you can consider the following solutions:

1. Create a custom nested frame template as per the Template Customization. article and manually add the "FullTextSearch" action container into it. This solution appears to be the most difficult from the implementation and further maintenance points of view.
2. Customize the default mapping of Actions to the default Action Containers in the Application Model. To do this, invoke the Model Editor and follow this video:


Take special note that It is important to make a copy of the Action definition and place it into the Action Container (e.g., Link), which is NOT present in the main, detail and lookup control templates to avoid duplication of Actions in the UI:


This solutions appears to be the easiest one from all points.

3. Enable native filtering features of the underlying grid, tree and other data bound controls used in nested ListView. For instance, the Find Panel or Auto Filter Row features also provide very good filtering experiences many of your clients will love.  The only disadvantage (which can be noticeable in advanced scenarios only) is that with the standard FullTextSearch Action you can provide common customizations for root and nested ListView using the events and other extensibility points of our FilterController, while for the native control features, you will likely have to implement platform-dependent customizations.

Friday, March 24, 2017

Faster opening of DetailView with many visible ListPropertyEditors (not in tabs) in complex XAF solutions with lots of Controllers - YOUR FEEDBACK IS NEEDED!

What is behind this optimization? 


With XAF v17.1, we have introduced some optimizations with regard to Controller creation for a Frame inside ListPropertyEditor, which is usually used to represent associated detail collections. That main idea behind this optimization is filtering out certain Controllers by their TargetXXX properties and not creating them at all .On our test machines, which are often multi-core i7 monsters with 16GB ROM, the loading time after this optimization was cut on 0.2-0.3 seconds or on 20% depending on the view configuration (we expect double time on your real client machines with budget i3-i5 or lower CPUs).

Specially for early testing 1-2 months prior to the official release, we have introduced a feature toggle in the current XAF v16.2 and showing this feature there as a preview


When should I be interested in this?


You can skip this post if you do not have many custom Controllers in your apps, because the effect of our optimization will unlikely be noticeable in your case.

You must definitely read further if you have hundreds of own Controllers + use third-party modules like Xafari/eXpand with many custom Controllers in them.

Another condition is DetailView layout configuration, which I would rather clarify with a couple screenshots:



If you have the A configuration, you will NOT benefit much from the optimization we introduced, because there is only one visible ListPropertyEditor in the active tab that affect the overall parent DetailView opening. 

If you have the B configuration, you have several visible ListPropertyEditors that require creating Controllers for their nested Frames immediately with the opening of the parent DetailView and thus slow things down a little. You can either turn our optimization on or consider hiding these ListPropertyEditors behind the tabbed group.

How do I test this right now?

Please download the latest  DevExpressComponents-16.2.5.17082.exe build and set the new XafApplication.OptimizedControllersCreation property to True in the constructor of your XafApplication descendant located in the YourSolutionName.Wxx/WxxApplication.xx file (or in the YourSolutionName.Win/Program.xx or YourSolutionName.Web/Global.asax.xx files), e.g. as follows:

namespace MainDemo.Win {
public partial class MainDemoWinApplication : WinApplication {
public MainDemoWinApplication() {
InitializeComponent();
                        this.OptimizedControllersCreation = true;
}

Monday, March 20, 2017

More enhancements to the High DPI support in WinForms XAF applications - YOUR FEEDBACK IS NEEDED!

A month ago, I announced the High DPI support in WinForms XAF applications. 

XAF team continues making improvements in this area based on your great feedback in Support Center. We would like to share our progress with you and would greatly appreciate your leaving a comment here.

Tuesday, March 14, 2017

New ways to customize the New Action's items list in XAF v16.2.5 - YOUR FEEDBACK IS NEEDED!!!

Changing the way how the New Action's items list is populated is quite an often task. The default behavior when the current types and all its descendants are added may be inappropriate in large XAF applications with a complex business objects inheritance hierarchy.



That is why we have decided to provide more built-in modes of populating this list. The available modes are listed in the DevExpress.ExpressApp.SystemModule.NewObjectActionItemListMode enumeration.

ValueDescription
DefaultThe current type and all of its descendant types are added.
ExcludeBaseTypeAll descendants of the current type are added. The current type itself is excluded.
LastDescendantsOnlyOnly the last types in the inheritance hierarchy of the current type are added.

XAF app performance: Reducing the number of simultaneous database connections



Multiple simultaneously opened connections consume your database server memory and thus, have negative impact on your application performance. To diagnose this situation, you can use the following SQL script:

SELECT 
    DB_NAME(dbid) as DBName, 
    COUNT(dbid) as NumberOfConnections,
    loginame as LoginName
FROM
    sys.sysprocesses
WHERE 
    dbid > 0
GROUP BY 
    dbid, loginame

Thankfully, there is a couple of tricks to optimize your existing apps in production (they are already applied out of the box in new projects).


Friday, March 10, 2017

XAF ASP.NET WebForms v16.2.5 - Beware of the missing Edit Action after navigating to dashboard items


I want to draw your attention to the T490025: WebEditDashboardController hides the Edit Action of ListViewController and doesn't reactivate it issue, which is already fixed in XAF for v16.2.6. This thread contains a simple temporary solution if you came across a similar use scenario (hotfix installation will be available later).



Wednesday, March 8, 2017

Preview of toast notifications using a platform-agnostic method in XAF v16.2.5 - YOUR FEEDBACK IS NEEDED!!!

I am still forcing myself to go to sleep after watching an unreal football drama in Barcelona, so I am writing this short blog post at night.
Besides Visual Studio 2017 official support, XAF v16.2.5 delivers a small gem, which I cannot hide from you too long. Remember that this is an early preview of the functionality we hope to officially release by v17.1 and which is have polished in the coming 2-3 months. So, your feedback is welcome, as always!

Typical usage

Let's modify the platform-agnostic Controller from our demo (C:\Users\Public\Documents\DevExpress Demos 16.2\Components\eXpressApp Framework\SimpleProjectManager\CS\SimpleProjectManager.Module\Controllers\ProjectTaskController.cs) by adding the Application.ShowViewStrategy.ShowMessage call at the end of the Execute event handler:
...
            markCompletedAction.Execute += (s, e) => {
                IObjectSpace viewDataContext = View.ObjectSpace;
                foreach(ProjectTask task in e.SelectedObjects) {
                    task.EndDate = DateTime.Now;
                    task.Status = ProjectTaskStatus.Completed;
                    viewDataContext.SetModified(task); // Mark the changed object as 'dirty' (only required if data properties do not provide change notifications).
                }
                viewDataContext.CommitChanges();
                //viewDataContext.Refresh(); // Optionally update the UI in accordance with the latest data changes.
                Application.ShowViewStrategy.ShowMessage(string.Format("{0} task(s) have been completed!", e.SelectedObjects.Count), InformationType.Success, 4000, InformationPosition.Top);
            };
...
Now, let's start the Windows and Web apps, select a few uncompleted tasks in the ProjectTask ListView and execute the Done! command from the menu.

Result in the UI for various platforms

Web
A nice notification window is managed using the dxToast widget (invoked via the  DevExpress.ui.notify method) from our DevExtreme HTML5/JavaScript library:



Tuesday, March 7, 2017

How to change an Application Model option globally or for multiple nodes

I have recently updated one of the articles on the subject in our support knowledge base and wanted to test-drive this content with you: https://www.devexpress.com/kb=T271022


Since the Application Model basically represents a skeleton of the application UI, based on which visual controls for supported platforms are created at runtime, updates to various options in the source UI metadata (both at design time and runtime) can be a good and often platform-agnostic alternative to customizing underlying controls directly in Controllers or other UI entities (examples: one, two, three). The most difficult thing is to perform this update at the right moment or using the right event in the View life cycle!
Even though this may sound like a quite an advanced topic, this is one of the core concepts for our framework, which I recommend you get familiar with.







Your feedback is welcome, as always!

We also hope to use this KB as a base for future updates of the online documentation at  Concepts > Application Model  for easier discoverability, so your early feedback on the main methods I described is welcome. In particular, I would greatly appreciate your comments on whether you experienced the scenarios needed runtime Application Model updates and exactly which techniques you used (e.g., #2.1, 2.2 or all ).


How to customize the New Object Action with a single item to display a simple button instead of a dropdown in WinForms


UPDATE:
See the latest post on this matter at Usability change for SingleChoiceAction with a single sub-item - YOUR FEEDBACK IS NEEDED!!!
-----------------------------------------------------------------------
I would like to promote an updated/simplified v16.2 solution for this task after introduction of the ActionBase > CustomizeControl event. To remind you the context, let me quote myself from the https://www.devexpress.com/kb=Q497985 thread:



"XAF allows defining whether a SingleChoiceAction click should show a dropdown or execute an action item immediately using the ShowItemsOnClick and DefaultItemMode  properties. You can easily change these properties based on the number of the New action items. However, a triangle glyph is always shown by default. The SingleChoiceAction does not currently provide built-in means for replacing a dropdown with a simple button either. Currently, to improve user experience with such configurations, you can customize the underlying bar item in the YourSolutionName.Module.Win project.


You can use the following controller to hide a drop-down list from the NewObjectAction in case it contains only one element:


using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Actions;
using DevExpress.ExpressApp.Win.SystemModule;
using DevExpress.XtraBars;
...
namespace YourSolutionName.Module.Win.Controllers {
    public class CustomizeNewActionController : WindowController {
        BarButtonItem newActionBarButtonItem;
        protected override void OnFrameAssigned() {
            base.OnFrameAssigned();
            WinNewObjectViewController newObjectViewController = Frame.GetController<WinNewObjectViewController>();
            SingleChoiceAction newObjectAction = newObjectViewController.NewObjectAction;
            newObjectAction.CustomizeControl += NewObjectAction_CustomizeControl;
            newObjectAction.ItemsChanged += NewObjectAction_ItemsChanged;
        }
        private void NewObjectAction_ItemsChanged(object sender, ItemsChangedEventArgs e) {
            if(newActionBarButtonItem != null) {
                SingleChoiceAction newObjectAction = (SingleChoiceAction)sender;
                int choicesCount = newObjectAction.Items.Count;
                if(choicesCount == 1) {
                    newActionBarButtonItem.ButtonStyle = BarButtonStyle.Default;
                }
            }
        }
        private void NewObjectAction_CustomizeControl(object sender, CustomizeControlEventArgs e) {
            newActionBarButtonItem = e.Control as BarButtonItem;
        }
    }
}




Here are screenshots showing the results in the application UI before and after this customization.


Before


After


Also, you can use the same approach with the CloneObjectAction (it is a part of the CloneObjectViewController). Refer to the following documentation articles to learn more about this solution:
    Concepts > Extend Functionality > Built-in Controllers and Actions 
    Concepts > Extend Functionality > Customize Controllers and Actions 
    Task-Based Help > How to: Customize Action Controls
    DevExpress.XtraBars > BarButtonItem > ButtonStyle 
    DevExpress.XtraBars > BarButtonItem > ActAsDropDown 


For older versions
Check out the How to display a dropdown without a triangle glyph for a SingleChoiceAction ticket for code examples."

Thursday, March 2, 2017

Opening a navigation item in a separate web browser tab (shipping in v16.2.5)

This is another follow-up on the EnableMultipleBrowserTabsSupport feature after receiving great user feedback in this blog and via other channels (see my previous post in this regard for more details).

With the recently released XAF v16.2.5, you can open a View in a separate browser tab directly from navigation. To enable this mode, set the static NavigationActionContainer.UseLinks static property in the YourSolutionName.Web/Global.asax.xx file:

        protected void Application_Start(object sender, EventArgs e) {
            WebApplication.EnableMultipleBrowserTabsSupport = true;
            DevExpress.ExpressApp.Web.Templates.ActionContainers.NavigationActionContainer.UseLinks = true;


When this mode is enabled, an Anchor element is added into nodes of the ASPxTreeView control and into items of the ASPxNavBar control. 
This feature allows you to use generic browser techniques to work with links such as a right mouse button click for context a menu, a Control key press or a mouse wheel click (currently, the approach described in the http://apple.stackexchange.com/questions/170731/how-to-open-link-in-a-new-tab-via-shortcut-in-chrome-on-mac article will not work for Macs).




ASPxGridView/ASPxGridListEditor + Server Mode + Select All = ?

I want to pay your attention to this Support Center ticket describing a recent fix for our ASPxGridListEditor, which is a wrapper over the ASPxGridView component as you know.

It is a known and pretty logical Server Mode limitation that the selection of ALL grid rows using the built-in SelectAll check box is NOT supported in this mode. That is because this particular operation defeats all server mode benefits = causes loading the whole data source into the web server memory...

Our ASPxGridListEditor did not manage the "Select All" header cell visibility prior to v16.2.4. We have corrected this mistake and now this button is hidden in server mode by default (SelectAllCheckboxMode = None). The "Select All" button is still available in Client and DataView modes only (SelectAllCheckboxMode = AllPages), though.


If you want, you can implement a custom Controller from the ticket to enable selection of all records on the currently active page only when DataAccessMode = Server (we did not follow this route in the XAF code, because it would be more confusing and even damaging for users who got used to this command). Alternatively, you can set DataAccessMode = Client/DataView  for a required ListView node using the Model Editor (of course, it you do not have many data records).


If these solutions do not help, please describe your real life use-case scenario where this SelectAll feature is needed when grid is operating in server mode. It is possible that we have an alternative and even better technical solution for you, e.g. like we did for Reinhold and his reporting scenario.



Wednesday, March 1, 2017

How to display an embedded report preview form in a Web app from a hyper link included into email

I cannot help sharing an interesting customer scenario and the solution we created for it:


This is all about Web apps and reporting, so I anticipate it can be helpful for many businesses. 

Finally, I think it will be helpful to know that a report preview can be invoked not only a popup, but also as an embedded DetailView. 
This is controlled by the ReportsAspNetModuleV2 > DesignAndPreviewDisplayMode option.


As always, I look forward to hearing your thoughts on this.