Search This Blog

Wednesday, January 21, 2015

Simplifying integration of custom controls bound to data from XAF application database - YOUR FEEDBACK IS NEEDED

Scenario


We are researching options to make it easier for our users to achieve the subject in the next version. One of the popular scenarios we were aware of from our users was integration of custom controls, often created in Visual Studio using the standard WinForms or ASP.NET WebForms approaches, and primarily designed for presenting data from the XAF application database in some very custom manner so that built-in XAF Property Editors  or List Editors were not good for this. For instance, you might want to show a list of records in a fancy grid with cards, image gallery or other controls or modes not integrated by default.




Current solutions and problems

XAF is very extensible framework and offers many ways of integrating custom or third party controls. We noticed that while doing so, feeding these custom controls with data from the application database was often a challenge for our users. This binding is done automatically for built-in forms and data editors, but requires writing some code that will read data via the IObjectSpace.GetObjects<T> method (to respect data security filters) and also listen to the IObjectSpace.Reloaded and other events to handle data updates. Finally, designing a data bound user control in Visual Studio often implies a direct connection to the database or using specialized data sources (e.g., to generate a list of grid columns or pivot fields), which do this for you. The latter forces you to think about obtaining an application connection string at design time, while this dynamic part is changed later in the most cases. Add to this different approaches for Entity Framework and XPO and you will get the whole picture.

New solutions (not yet built-in!)

Briefly, we decided to simplify this scenario. Here are two videos that shows one possible option:

ASP.NET:  http://www.screencast.com/t/OHhcHD9vy

WinForms: http://www.screencast.com/t/8M8K4eskkYO9

How it works?


In short, the proposed flow is as follows:



1. Create a custom user control
2. Drop a specialized XAF data source from the Toolbox, bind a control to the data source and use the full capabilities of visual designers;
3. Implement an interface by your custom user control and bind it to data obtained from IObjectSpace automatically supplied by XAF at runtime.
4. Use built-in ControlDetailItem or WebUserControlViewItem to link your custom user control with an item within DashboardView.
5. Display that DashboardView from navigation or other places via standard XAF approaches for showing Views.

These approaches are very similar to what we demonstrated in the How to show custom forms and controls in XAF example with the only difference is that it is also possible to customize the user control via the visual designer based on the structure of your business model via a specialized XAF data source component. This component is bound to the real data from IObjectSpace at runtime via the built-in IXafCustomControlWithDataSource interface implemented by your custom user control like in the example.

We recommend creating reusable user controls for such tasks instead of forms, because this way it is easier to embed the control within the built-in DashboardView, which in turn is already well-integrated into the XAF infrastructure. For instance, you won't need to handle Tabbed MDI and other complex situations manually if you use the proposed solution.

Feedback

We are eagerly looking forward to your feedback on this. If you had other difficulties integrating custom controls in XAF, please let us know so we can consider handling them as well.

UPDATE 1:
In the latest XAF version we introduced the the DevExpress.ExpressApp.Editors.IComplexControl interfac instead of the IXafCustomControlWithDataSource  one shown in my original video:
public interface IComplexControl {
void Setup(IObjectSpace objectSpace, XafApplication application);
void Refresh();
}

The CustomUserControlViewItem class from the video was also renamed into WebCustomUserControlViewItem.


UPDATE 2:
See the following articles in the Task-Based Help section of the official XAF documentation:

30 comments:

  1. Replies
    1. @pbot84: Thanks for your feedback! Am I correct that you experienced the same problem and liked the proposed solutions? If you experienced other difficulties integrating custom controls in XAF, please elaborate on a few most popular scenarios and problems.

      Delete
    2. I'm afraid I cannot deliver more feedback in this cause I am trying to not integrate custom controls. It is always looked hard for me.
      It would be nice if You will integrate more DX controls to XAF out of a box. For example: spreadsheet editor, maps editors (google maps), etc.

      Delete
    3. Thanks for your answer, pbot84. While having all DX controls integrated in XAF by default would be great, the resources are finite and so we are trying to simplify the process of custom controls integration by learning exactly what was hard and fixing it.

      Delete
    4. While resources may be finite Dennis, we don't need this to be a binary state in terms of response.

      DX should at least make an effort to implement *some* of the new editors which have been added to the Universal toolset - and support these as first class citizens and not "examples".

      The expectation is not for ALL new stuff - but some would be nice.

      Delete
    5. I appreciate your feedback on this, Chris.We are monitoring user requests in this regard and collecting scenarios, which can be generalized and implemented on our side. We are also focusing on the core improvements as this stuff cannot be done by customers on their own (unlike integrating custom editors).

      Delete
  2. Dennis, that looks very interesting indeed, and has brightened an otherwise gloomy winter day:

    - Q. How would one handle captions/labels etc where these renamed/translated values exist in the model (I'm guessing something like an explicit model lookup)... ditto edit & display formats etc
    - Q. Also, would there be some form of a call to the appearance engine to be able to update accordingly,
    - Q. Is the coding to retrieve active filters & filter changes "simple" to hook into (refering to the ListView example)
    - O. Even with the code to make it easier to add controls, it'd still be very useful if DX extended the "toolbox" of built-in controls to include some of the more recent additions e.g. an Excel property editor, a Word capable property editor, a script capable property editor, map capable etc
    - O. We currently have a use case which may be reasonably complicated but useful when considering how this functionality might work, and what events / interface methods would be useful:
    - We have a lookup table of Category items,
    - We have a number of Product items,
    - We have a Product 1n ProductCategory association (which contains Product, Category properties)
    - In order to assign a category against a product, the user currently needs to go to a LV, Add new, choose category etc. This is time consuming. What we'd like is something like a check list editor which lists all Category items & ticks those which exist in ProductCategory for the current Product. Then the user can tick/untick & the underlying collection is added to / deleted from.
    - So, in many respects this is like the CheckedListBoxPropertyEditor used in the security system. The key differences are that we want to prime the available values from a collection, the "selection" from another collection, and we want to handle the persistence in terms of processing Adds/Deletes.

    ReplyDelete
    Replies
    1. Thanks, Chris. I appreciate your input and will answer you later.

      Delete
    2. Chris:
      Thanks for your feedback.
      A1: One can write custom code within its control to modify default captions based on the CaptionHelper API (https://documentation.devexpress.com/#Xaf/clsDevExpressExpressAppUtilsCaptionHelpertopic).
      A2: No, ConditionalAppearance and most of other functionality of XAF system modules is supposed to work only with pure XAF abstractions.
      In general, we assume that within custom forms and controls you would use standard development approaches as without XAF. From our side, we help you simplify the processing of feeding this custom controls with the required information from the XAF application.
       
      A3: It is easy to retrieve the Criteria and Filter values from the ListView node in the Application Model. For this, a custom control can accept the XafApplication object. In general, we think about reusing the IComplexViewItem.Setup(IObjectSpace, XafApplication) interface for that purpose.
      A4. Thanks, I remember your request from our previous conversation on the subject.
      A5: I appreciate your describing a concrete business scenario and current difficulties with it. A checked list box indeed looks like something that can simplify this task for end-users. Your custom ListEditor implementation can support the IComplexListEditor interface to obtain XafApplication and CollectionSource for handling various operations with the control. We will take your input in this regard into account and monitor similar feedback in the future. Should you experience any difficulties with your custom ListEditor implementation, do not hesitate to contact us.

      Delete
    3. Re. A2, I think the desire is to be able to be notified of effective appearance rule changes & then process these against a custom control via e.g. a IAppearanceAwarePropertyEditor. I'm not sure what form this would take really, but it'd be nice of appearance system communicated with controls via interfaces (and it might already do this).

      Delete
    4. Thanks, Chris. If you really need to track these changes, there are already interfaces like ISupportAppearanceCustomization, IAppearanceFormat, IAppearanceEnabled, IAppearanceVisibility as well as their implementations for standard XAF UI abstractions and Controllers that connect this stuff together. Of course, it is possible to create custom-tailored implementations for your custom form or controls.

      Delete
    5. Excellent, I thought there would be, thanks for confirming.

      Clearly if you do knock up some examples, that & localisation would be good to include in the example.

      Delete
    6. You're always welcome.
      Would you please describe your current difficulty with the localization? It seems that my previous help link (https://documentation.devexpress.com/#Xaf/clsDevExpressExpressAppUtilsCaptionHelpertopic) should have helped already...
      As for examples using these interfaces, this is quite low level stuff, to be honest, and I am not sure if will be interesting for others. Users who need to learn more on this there already good examples within the XAF source code. In particular, you can examine the WinLayoutManager, GridListEditor, PropertyEditor classes code as well as Controllers from the ConditionalAppearance module. If there is anything I can help you with, drop me a line, as always.

      Delete
    7. There may well be good examples of various things distributed elsewhere Dennis. (Personally I don't have any "difficulty" - I've been using XAF since beta stage). The purpose of this development was I thought to make this task easier & more approachable for newer XAF developers.

      If you're creating an example, why not create it as a reference example so that people can refer to this for *best practices* ?

      When we're talking implementing property editors, continuity of UI & language are important parts of a polished UI. Much easier to produce one useful example than pointing people at a number of different support threads to find the answer for themselves.

      You make think it's low level stuff - but to users form can be as important as function.

      Delete
  3. Great feature.
    Do you plan to deliver additional interfaces for creating custom "DetailViews" or "Popup Windows" too? That would be great.

    ReplyDelete
    Replies
    1. PS:
      >> "to achieve the subject in the next version" ..
      14.2.5? :o)

      Delete
    2. Jens, thanks for your feedback. As long as you use DashboardView to host a custom user control you can display it as popup using standard XAF means.
      Would you please elaborate a bit more on your requirements for "custom DetailViews"?

      Delete
    3. >> Would you please elaborate a bit more on your requirements for "custom DetailViews"?

      I had some use cases where I wished to have a WInforms based DetailsForm, to edit the current MasterObject.

      2 Examples:

      1) A BO has an Image Property. Within the DetailView the customer likes to draw somthing in that image (let's say a singature or a stamp overlay). That's easy to do with a Painbox Control and some buttons.

      2) A BO has a String Property that does contain a CSV String. Within the DetailView the customer likes to change the order of the CSV columns by drag&drop. A ListBox Control and some buttons to add and remove items would be fine here.



      Delete
    4. Jens, thanks for answering. As far as I understand, showing a standard XAF DetailView with a custom PropertyEditor (based on any custom control) is not an option here, correct? If so, I am trying to understand how we can simplify this scenario for you. What was your main difficulty when implementing this custom form?
      In any event, a standard XAF DetailView with a custom PropertyEditor would be a way easier to implement than a custom form, unless I missed something.

      Delete
    5. In my current understanding a custom Win-/WebPropertyEditor descendant can change a single BO property at a time. That may work in the most scenarions. I hadn't realized that before.
      But I wish anyway that I could have a simple kind of custom DetailView, that holds the MasterObject and provides the ObjectSpace connectivity and the XAF logic behind. Where I can change all MasterObject BO Properties in a single step, simply "forms based", with any control I like to use, without the need to create a lot of custom property editors.

      Delete
    6. Thanks for posting back - I am always happy to help with how things work in XAF!

      I do not fully understand the "the XAF logic behind" you meant, but it seems that the new solution I described originally will be good for feeding your custom controls with the IObjectSpace functionality. If not, please send me a test project with a custom form you built in your real project in the past so we can research it - it is simply difficult to simplify or improve the current process for you without understanding it and seeing your difficulties with this approach. Thanks!

      Delete
  4. Hi Dennis,

    I have followed you Web example video and implemented the IComplexViewItem interface in the web custom control. I had anticipated that this would also implement full CRUD capability but this doesn't seem to be the case. I have select Show/All Edit etc in the Grid setup but when I press edit nothing happens. Is there more to be done beyond what you show in the video to achieve this?
    Thanks

    ReplyDelete
    Replies
    1. Update: I've added the KeyFieldName to the Grid in the custom control form. It now shows the edit form but after pressing update the underlying data is not updated.
      Thanks

      Delete
  5. @Ken:
    Thank you for taking your time to test the introduced improvement!
    >>
    I had anticipated that this would also implement full CRUD capability but this doesn't seem to be the case.
    <<
    As described in the article, this interface is merely supposed to simplify one particular task - feeding your custom user control with data from the XAF application database. In other words, you should configure the underlying user control exactly as in traditional development to achieve what you want and XAF will make it easier to embed this control into the XAF form.

    Honestly, I am not sure how you would like us to implement full CRUD capabilities if the latter fully depend on a particular data-bound control you use. Would you please elaborate a bit more on how you see an ideal solution here?

    ReplyDelete
  6. Hi Dennis,

    Thank you for your answer. As I mentioned I followed your example with a devexpress Aspxgridview and everything worked up until I tried to do any inserts updates. The Grid as populated with the XafWebDesignDataSource as per example. Does this not support CRUD or am I missing something?

    Thanks

    ReplyDelete
  7. Hi Ken, like I have already answered above you should implement CRUD functionality yourself as per the ASPxGridView documentation in a regular non-XAF application.

    ReplyDelete
  8. Hi Dennis

    The title has in large capital letters that you are looking for feedback.

    I am lost when it comes to taking your example beyond the point where your video stops. I am trying to implement CRUD & happily do it myself but I have no idea how to start when the data is coming from the XAF objectspace.

    If you can't be bothered to answer just say so and I'll stop.

    ReplyDelete
    Replies
    1. @Ken: First of all, I greatly appreciate your feedback in this regard. You can always contact me via email at dennis no spam devexpress dot com or leave a comment in this blog, which I monitor.

      >>
      I am trying to implement CRUD & happily do it myself but I have no idea how to start when the data is coming from the XAF objectspace.
      <<
      I am trying to understand how is this case with XAF data different...Probably the https://documentation.devexpress.com/#Xaf/CustomDocument3711 documentation article will help you see how to obtain data from the IObjectSpace and also implement CRUD functionality. If you need any assistance on configuring CRUD with ASPxGridView, do not hesitate to contact the ASPxGridView product team or check out the corresponding documentation and examples for this control.

      Delete
  9. Dennis

    I am begging you....

    Please redo the video you did and then complete it with Create , Update, and Delete on the Contact object. I promise you it's not as easy as you are suggesting. Or post and completed example! The XAF community will love you for it!!

    Ken

    ReplyDelete
  10. @Ken: We will take your input into account for the future and consider creating such an example in the XAF knowledge base.
    Right now, you can contact our ASP.NET support team for assistance on this task (if you have already checked the ASPxGridView documentation and examples and could not find the answer yourself), which a great many ASPxGridView developers solve outside the XAF world. I believe you will have a solution description for the grid control within a business day or earlier.

    ReplyDelete