Search This Blog

Thursday, September 15, 2016

Simplifying customization of Action controls - YOUR FEEDBACK IS NEEDED!

As you know, XAF provides abstractions for common UI elements like list and detail forms, their editors, main and navigation menus, etc. that enable XAF developers to accomplish common tasks for several supported platforms with less effort. Today I want to take a moment of your time and focus on popular customization tasks related to Actions - typically abstract UI elements that allow you to perform specific operations in response to end-user manipulations.



For instance, the ActionBase class, which is the super class for all Action types provides many useful members like Caption, ToolTip, Shortcut, PaintStyle, Enabled, Active, etc. that help you care less of technical implementation details for each specific platform or situation, at least for the popular tasks these members were designed for. It is also super easy to manage these properties and events in code or via the visual designers like the Visual Studio component designer for Controller or our own Model Editor.




Current approaches for customizing Action controls

The above looks very well (and many XAFers expressed this is one of the things they love the product for) and we have always been trying to keep this promise when designing our framework:
common and simple tasks can be done easily, while any specific or complex tasks are technically possible

But what about the second part of this promise with regard to Actions in practice? To answer this, it is best to evaluate it yourself for various tasks. Our documentation and support knowledge base contains many code examples for customizing Action controls in various places of an XAF application, and I grouped them below for your review.

Navigation menu Actions
WinForms/WebForms: How to: Access Navigation Control

Main menu Actions
WinForms:How to: Customize Action Controls
WebForms: Various examples from the Support Center: onetwothree and even more

Layout Actions (aka ActionContainerViewItem)
WinForms: Various examples from the Support Center: onetwo and even more
WebForms: Various examples from the Support Center: onetwo and even more

Inline List Editor Actions
WinForms: Not applicable.
WebForms: Various examples from the Support Center: onetwothreefourfive and yet more for ASPxGridListEditor.

Current considerations and ideas for possible improvements

As you can see, there is currently no unified or intuitive approach for these tasks as opposed to customizing View and its editors with their famous View.ControlsCreated and ViewItem.ControlCreated events. Also, certain things are not well documented as of now, e.g. methods for Web menu items and inline actions. This is something that concerns me from both developer usability and learning experience/support traffic points of view after having researched a large number of various user scenarios related to this topic.

Idea 1: Intuitively, I think it would be much easier for XAF developers to have an event like ActionBase.ControlCreated with the ControlCreatedEventArgs providing access to some IActionControl ActionControl + probably some additional context like current View, CurrentObject, etc. This "the XAF-way" event is supposed to be raised once when an Action control is being initialized. The IActionControl interface is implemented by specific Action controls like BarEditItemParametrizedActionControl.  

public class ControlCreatedEventArgs : EventArgs {
public ControlCreatedEventArgs(IActionControl actionControl) {
ActionControl = actionControl;
}
public IActionControl ActionControl { get; private set; }
}
    public interface IActionControl {
        void SetVisible(bool visible);
        void SetEnabled(bool enabled);
        void SetCaption(string caption);
        void SetToolTip(string toolTip);
        void SetImage(string imageName);
        void SetConfirmationMessage(string confirmationMessage);
        void SetShortcut(string shortcutString);
        void SetPaintStyle(ActionItemPaintStyle paintStyle);
        string ActionId { get; }
        object NativeControl { get; }
        event EventHandler NativeControlDisposed;
    }


The problem with this approach is that the interface methods above do not fit well in certain cases (= they will do nothing or throw NotImplementedException), e.g. with the navigation control. Also, the use of these SetXXX methods can be dangerous sometimes, e.g. when you override the default value set from ActionBase.XXX properties.


Idea 2: There will be a set of new CustomGetXXX events for all popular ActionBase members, like the CustomGetTotalTooltip and CustomGetFormattedConfirmationMessage ones we already have there. These new events are required not only for ultimate flexibility, but also to avoid potential problems with overriding the default values I was talking about in Idea 1. Note: there will still be this universal ControlCreatd event, but its event arguments will just have the "object NativeControl" property (i.e., without any IActionControl). We will recommended handling this event for scenarios, which cannot be solved with the ActionBase.XXX properties or ActionBase.CustomGetXXX events.


Common:
From an XAF developer perspective, a subscription to these events can be done from a custom Controller and may look as follows:


   public class MyController: ViewController {
        protected override void OnActivated() {
            base.OnActivated();
            var systemAction = Frame.GetController<ShowNavigationItemController>().ShowNavigationItemAction;
     systemAction.ControlCreated += systemAction_ControlCreated;
            myOwnAction.CustomGetTotalTooltip += myOwnAction_CustomGetTotalTooltip;
        }
   }

Specific scenarios that are still under consideration

There are also some rare and specific cases where we plan to recommend our users use the same old customization methods, which imply accessing the underlying native control directly or using a ready XAF abstraction and customizing it according to its documentation. For now, these are:
1. Dynamic customizations at arbitrary moments and not only when the Action control is being initialized. For instance, changing the navigation item caption on timer tick or selection like in this ticket
2. ASPxSchedulerListEditor and ASPxTreeListEditor inline Actions - these are just too rare scenarios as far as we are aware off.
3. Customizations of the same Action controls in duplicate Action Containers.  For instance, in WinForms these are the same bar items in the main and context menus; in WebForms, these are the duplicate SaveXXX Actions at the bottom and at the top of the Classic Web UI layout. We think that it is very rare when people may want to customize very same controls in various places differently as it may confuse end-users.

Please let us know what you think of the highlighted scenarios or if I am missing something popular or important.

Survey questions

Even though I have already prepared several Controller files showing what the suggested ideas might look like in code for the aforementioned scenarios, today I want to focus not on this new solution, but more on your real development problems with regard to customizing Action controls in general. I am also fine to hear that it is not a problem for you at all, because I am just validating my ideas and knowing what happens in reality for sure is also very helpful. This way, we can continue working on something more important.



So, if you faced a requirement to customize Action controls to better meet the needs of your clients, I would greatly appreciate it if you email me at dennis@devexpress.com (or just leave a comment here) and tell the details of your real use-cases and related problems. To formalize this a bit and make it easier for you to answer (and for us to process too), see the three simple questions:


1. Would you please post the resultant code illustrating your current solution (I believe the original use-case scenario must be clear from the Controller code)? If there were several scenarios, please provide descriptions and attach source codes for all of them for us to analyze.
2. How costly is your current technical solution in terms of implementation time and maintenance resources? Please let us know if you experienced any problems with it or wanted to improve anything.


3.
Which of the two new ideas (1 or 2) would suit you better for such tasks? If you thought of an alternative or an "ideal" solutions for your problems, please provide their description and maybe real/pseudo codes here.



If you have not needed such customizations so far, that is also fine and I would kindly ask you to just leave a short comment about this fact.


I look forward to hearing from you, and, if needed, I will be happy to email you back more information on the proposed ideas (four Controllers with pseudo codes for Windows and the Web) and discuss them and our other considerations in greater detail. As always, thanks for making our framework better!

4 comments:

  1. While I don't believe we have needed to customize action controls (yet) it seems like a good idea to make it possible with the necessary events. Most of the actions we've used so far are either Simple (button), PopupWindow (also a button) or SingleChoice - so far have not needed parameterized actions in our apps. I think there was a simpleAction I wanted to customize the caption based on the state of the selected object, but found this to be difficult so just created 2 simple actions and enabled/disabled accordingly (this was a XAF/ASP.net app)

    ReplyDelete
  2. Hi Dennis,

    Thank you for your article.

    I am learning new bits of XAF every day.

    Let me share two parametrized actions scenarios that hopefully will help you in designing new features:

    1. DateTime parametrized action
    Enable the user to select a date to filter a view. The actual standard XAF implementation needs to be expanded:
    - Additional small buttons are required to easily navigate to next/previous/today date. At the moment, the user needs a first click to drop dowm, the click the other date, then press the "Go" button.
    - Immediate postback is required, as well as other similar customizations.

    2. Date range filter parametrized action
    Create a composite parametrized action with a DateTime (like point 1)
    - including a "day", "week", "month" dropdown selector, to enable the user to select a period of time.
    - including a 1, 2, 3, 4, 5, 6 dropdown selector, to select the number of days, weeks, months period.

    hth

    ReplyDelete
    Replies
    1. Thanks for your feedback, Marc. I've recorded it and we will take it into account for the future

      Delete