New Posts New Posts RSS Feed: question about tutorial 210. Composing Forms with UserControls
  FAQ FAQ  Forum Search   Calendar   Register Register  Login Login

question about tutorial 210. Composing Forms with UserControls

 Post Reply Post Reply
Author
Dominique View Drop Down
Groupie
Groupie
Avatar

Joined: 28-Jun-2007
Location: Norway
Posts: 44
Post Options Post Options   Quote Dominique Quote  Post ReplyReply Direct Link To This Post Topic: question about tutorial 210. Composing Forms with UserControls
    Posted: 23-Nov-2007 at 2:36am
Hi,
i was looking at your tutorial "210. Composing Forms with UserControls" where you are displaying user controls on tabpages "on demand". Your solution is much cleaner than a 5000 LoC designer generated file but yet easy to understand. :-) (who said C.A.B. ?)
I see that the tapPage inherits from an abstract tab. This will prevent from opening them in the designer, so I guess that all the UI design should be push down to the user controls and that the tabPage is merely a container that could be changed with mdi or alike.
Could you confirm if I understand it right?

And another question about organizing the work flow of the application.
Say that I want be able to see the product ordered through a special sale rep. To achieve this I put a button on the employeeUserControl. When the user push the button she should see the product tab page filled with the products for that employee. How would you implement that without coupling the different part?

[edit:] uses product instead of orders in the story as orders are shown on the UI. the point is who is making the coordination betwenn the UI parts


Edited by Dominique - 23-Nov-2007 at 3:09am
Dominique
Back to Top
GregD View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 09-May-2007
Posts: 374
Post Options Post Options   Quote GregD Quote  Post ReplyReply Direct Link To This Post Posted: 27-Nov-2007 at 4:15pm
>> I see that the tapPage inherits from an abstract tab. This will prevent from opening them in the designer, so I guess that all the UI design should be push down to the user controls and that the tabPage is merely a container that could be changed with mdi or alike.

Could you confirm if I understand it right?
<<
 
Yes, that's correct. Each UserControl contains data bindings and editing controls related to a "single entity". [1]  The TabPage bears the same relationship to the containing Form as, in an MDI app, a Form does to the MDI container.
 
The UserControls are designed with reuse in mind. Note that the Orders UserControl is loaded into three different TabPages.
 
>>
Say that I want be able to see the product ordered through a special sale rep. To achieve this I put a button on the employeeUserControl. When the user push the button she should see the product tab page filled with the products for that employee. How would you implement that without coupling the different part?

[edit:] uses product instead of orders in the story as orders are shown on the UI. the point is who is making the coordination betwenn the UI parts
<<
 
If you look at one of the TabPages, say the EmployeeTabPage, you will see that it is the component that decides what will be displayed in the two UserControls that it houses.  It pushes the result of a GetEntities<Employee>() call into the EmployeeUserControl; and each time the user navigates to a new Employee, it pushes an appropriate set of Orders down into the OrdersUserControl.  (The TabPage learns that this navigation has occurred because it subscribes to the CurrentChanged event of the EmployeeUserControl's main BindingSource.)
 
In this scheme, the two UserControls, in and of themselves, don't know anything about each other: it is the TabPage that is doing the coordination.  So if you wanted a button to launch functionality that would let the EmployeeUserControl influence the OrdersUserControl, you could just put it on the TabPage.
 
Greg Dunn
IdeaBlade
 
 
--------
[1] I speak functionally rather than literally.  In this sample app, for the purpose of keeping things simple, I decided that the Order line items would always be displayed with (and below) a grid of Orders. But breaking out the OrderDetail grid into a separate UserControl would be a obvious alternative to be considered.  And in a real app one might have two UserControls for almost every entity type: one displaying a collection of instances of that type in a grid, another displaying a single instance using loose controls.
 
 
Back to Top
Dominique View Drop Down
Groupie
Groupie
Avatar

Joined: 28-Jun-2007
Location: Norway
Posts: 44
Post Options Post Options   Quote Dominique Quote  Post ReplyReply Direct Link To This Post Posted: 28-Nov-2007 at 12:10am
Hi Greg,

Thank you for your reply.
I am a fast learner, I just need som time to understand so I have some more questions. :-) Sorry for the lengthy post.

Could you correct me if I am wrong:
* A tabpage should handle a usecase (kind of a CAB workItem light if I understood that part of CAB)
* A tabPage controls the UserControls that it hosts
* A Usercontrol handles the UI for a "single entity", merely setting up databinding and showing what the tabPage pushs into it and firing events (CurrentChanged,UserWantCHeckIn, ...).

Is that correct that:
* the FrmMain manage situations where a use case interfere with an other one.
* the "use case controller" part of the code in the tabPage could be taken out if I want to have different UIs supporting the same Use case like flipping between mdi and tabs or having a web interface (to a certain extend).

Some further questions about the code in the solution.
1> I see that the UserControl uses a persistenceManager, wouldn't that break with the TabPage having the reponsability? like when the CustomerUserControl go get customers using it?
2> The use of an interface (IentityUserControl here) should open for loosing the coupling between a tabPage and a concrete UserControl but I can't see you are using it. Is their any reasons for that? (I am thinking of using Interface to have different lay out of the "same" control for different clients)


class EmployeeTabPage : TabPageBase {
    public override void LoadUserControls() {
      // EmployeeUserControl
      mEmployeeUserControl = new EmployeeUserControl();
[...]
    }

    void mEmployeesBS_CurrentChanged(object sender, EventArgs e) {
      Employee currentEmployee = (Employee)mEmployeeUserControl.mEmployeesBS.Current; // How to manage this when using the interface?
      mOrderUserControl.LoadMainData(new EntityList<Order>(currentEmployee.Orders));   // should it be an abstract EmployeeUCtrlBase instead?
    }

    public override void LoadData() {
      mOrderUserControl.LoadSupportingData();       //still ok through interface
      mEmployeeUserControl.LoadSupportingData();
[...]
    }

    #region Private Fields
    PersistenceManager mPersMgr = PersistenceManager.DefaultManager;
IEntityUserControl    mEmployeeUserControl;   // EmployeeUserControl mEmployeeUserControl;
    [...]


Thank you again for taking time to explain your code.

Dominique
Dominique
Back to Top
GregD View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 09-May-2007
Posts: 374
Post Options Post Options   Quote GregD Quote  Post ReplyReply Direct Link To This Post Posted: 28-Nov-2007 at 10:49am
>>
 A tabpage should handle a usecase (kind of a CAB workItem light if I understood that part of CAB)
<<
 
Yes, that sounds about right.
 
 
>>
* A tabPage controls the UserControls that it hosts
<<
 
Something has to, if the UserControls are to be independent, flexible, and reusable.  So yes, in this case, I chose the TabPage to do that.
 
 
>>
* A Usercontrol handles the UI for a "single entity", merely setting up databinding and showing what the tabPage pushs into it and firing events (CurrentChanged,UserWantCHeckIn, ...).
<<
 
More or less, but as I said, the "single entity" doesn't have to be literally a single type: just something you want to treat conceptually as one thing (like an Order with its line items).
 
 
>>
* the FrmMain manage situations where a use case interfere with an other one.
<<
 
I'm pretty sure the answer is "yes", but give me a "for instance" if you like.
 

>>
* the "use case controller" part of the code in the tabPage could be taken out if I want to have different UIs supporting the same Use case like flipping between mdi and tabs or having a web interface (to a certain extend).
<<
 
Sure, you could use some other container.
 
 
>>
1> I see that the UserControl uses a persistenceManager, wouldn't that break with the TabPage having the reponsability? like when the CustomerUserControl go get customers using it?
<<
 
Note (in EmployeeUserControl, let's say) that there are two overloads of the LoadMainData() method. One allows the calling code to push into the UserControl the collection of Employees to be used; the other loads all Employees. The one that loads all Employees is there as a convenience, to support a "default" scenario. It permits the TabPage to delegate to the UserControl the responsibility for deciding what Employees to load. But that's the TabPage's decision.
 
The other use of the PersistenceManager in EmployeeUserControl is to load "supporting data" - basically the collections needed to populate ComboBoxes on the form. For simplicity, my use case said those ComboBox item collections would be the same for all scenarios. If they're not, you could add a second overload of LoadSupportingData() that permitted the collections to be passed in.

>>
2> The use of an interface (IEntityUserControl here) should open for loosing the coupling between a tabPage and a concrete UserControl but I can't see you are using it. Is their any reasons for that? (I am thinking of using Interface to have different lay out of the "same" control for different clients)
<<
 
I'm just using the interface to guarantee that each UserControl will have a standard set of facilities, so that the containers that work with them (TabPages in this case) can do so in a consistent and predictable manner.  I don't see why you couldn't also use it as you suggest, however.
 
Greg Dunn
Back to Top
 Post Reply Post Reply

Forum Jump Forum Permissions View Drop Down