Print Page | Close Window

[COMPLETED] Widget View Template

Printed From: IdeaBlade
Category: DevForce
Forum Name: DevForce Classic
Forum Discription: For .NET 2.0
URL: http://www.ideablade.com/forum/forum_posts.asp?TID=423
Printed Date: 03-Jun-2024 at 12:38pm


Topic: [COMPLETED] Widget View Template
Posted By: Linguinut
Subject: [COMPLETED] Widget View Template
Date Posted: 10-Sep-2007 at 6:35pm

Again, great job on the templates/wizards!

I was playing around with creating a customer page with contact details.  I would like to present the contacts in a view with a navigator.  When reading about the summary view, I ran across the statement:
 
"use one of the widget view templates to create and design a new summary view"
 
I am not sure what a widget view template is.  What are these templates and how would I use them?
 
Thanks,
Bill



Replies:
Posted By: Bill Jensen
Date Posted: 11-Sep-2007 at 11:51am

So far, the two widget view templates are ControlView and DotNetGridView.  The others are considered layout view templates (except the GridBuilder which is a helper class template).

When building views, we recommend clearly separating the concept of "layout views" that define the structure of a portion of screen real estate and "widget views" that actually display data in a particular set of controls.
 
Bill J.


Posted By: Linguinut
Date Posted: 11-Sep-2007 at 12:00pm
Are there five classes of wizards, then?
 
1)  Application
2)  Business Module
3)  Page Layout
     a)  Search Summary/Detail
     b)  Search Results
     c)  Summary/Detail
4)  Views (widgets)
     a)  Grid (DotNet only?)
     b)  Controls
5)  Helper (only grid builder, so far)
 
If I build a layout the wizard can setup the view I would like with it; however, that view could easily be replaced by another view that I create with one of the widget wizards, right?


Posted By: Bill Jensen
Date Posted: 11-Sep-2007 at 12:15pm
Right.  You'd do that by modifying the page controller code for the layout view to create the desired widget view.
 
Bill J.


Posted By: Linguinut
Date Posted: 13-Sep-2007 at 10:09am
I built a loose controls widget for my address master table.  This table is related to the customer master table.  I have a page layout for customers using a search summary/detail layout.  My desire is to add the new address control to the tabs.  Here is my code:
 
TabViewControllers.Add(new GeneralTabViewController<AddressView>("Addresses","Customer Addresses", true));
 
When I run this I get the following error:

The item type of the BindingSource that you selected [Spiratex.Aspire.Model.CustomerMaster] does not match the BoundType of this BindingManager [Spiratex.Aspire.Model.AddressMaster].


I thought I could setup a view with relational ignorance; however, that does not seem to be the case.  How would I create a widget that will reflect related items and NOT be a readonly entity list?
 
Thanks!


Posted By: Bill Jensen
Date Posted: 13-Sep-2007 at 5:20pm
I'll be happy to help you with this (and the additional issues raised in your e-mail to support) when I return on Tuesday.
 
Bill J.


Posted By: Linguinut
Date Posted: 13-Sep-2007 at 5:25pm
When you get back, I'd appreciate some help on that ListConverter thing, too.
 
Thanks!


Posted By: Linguinut
Date Posted: 19-Sep-2007 at 3:35pm
This may be related to another concurrent thread; nevertheless, I thought I would get back to this today.
 
I am still getting the following error:

The item type of the BindingSource that you selected [Spiratex.Aspire.Model.CustomerMaster] does not match the BoundType of this BindingManager [Spiratex.Aspire.Model.ContactMaster].
 
I get this no matter how I try to connect a view to the customer summary/detail layout.  With or without a tabcontroller, this error keeps surfacing.  How do I properly connect a widget view to a layout view?
 
This is an example of what I am trying to do...both addresses and contacts are loose control views with navigation.  Orders and invoices will be simple grid views.
 
Customer%20Layout%20Example


Posted By: orcities
Date Posted: 19-Sep-2007 at 6:38pm
Glad to hear I ain't the only one.


Posted By: orcities
Date Posted: 19-Sep-2007 at 6:39pm
What did you do to add new buttons to the nav bar?


Posted By: Bill Jensen
Date Posted: 20-Sep-2007 at 10:00am
Look at a at the "NavBar Setup" region of a module controller.


Posted By: Linguinut
Date Posted: 20-Sep-2007 at 11:53am
My example above is from a previous, non-CAB version of my application.  I have only been successful in recreating the top part of that window in the CAB app.  The tabular portion is not working (unless I introduce a gridview, but that is not what I want).  I am still trying to connect a widget view (loose controls with navigation) to the overall layout.


Posted By: orcities
Date Posted: 20-Sep-2007 at 11:59am
I am right there with you. Haven't been able to get a reply tho.


Posted By: Linguinut
Date Posted: 21-Sep-2007 at 2:42pm
*bump*
 
The http://www.ideablade.com/forum/forum_posts.asp?TID=443 - recent discussion on the new base view has been somewhat relevant and helpful; however, my basic question is still unanswered:  how do I create a view with navigation similar to the example provided above?
 
My efforts so far have gone one of two ways:  1)  the view shows up (no navigation), but no data is presented; or 2)  the error regarding the boundtype resurfaces.  I have tried the view/context/presenter route.  I have tried creating a new tabviewcontroller just for the view.  The GeneralTabViewController does not work either (boundtype error).  I am running out of options.
 
Any help would be greatly appreciated.
Thanks,
Bill


Posted By: Linguinut
Date Posted: 21-Sep-2007 at 3:23pm
Quick update:  I now have data showing up in the view (the mEmptyList was pointing to the wrong entitylist).  However, it is presented without any way to add/edit or delete.  So, the next step will be to try to wiggle a BindingNavigator onto the form.  I'd really like to use the one already designed (summarydetailpage?), so I'll keep digging into the code to figure it out.


Posted By: Linguinut
Date Posted: 21-Sep-2007 at 5:35pm
One last effort for today was to create a Contacts SummaryDetailPage using the wizard.  From this I pointed the recently created ContactViewTabController to use the new ContactMasterSummaryView created by the wizard.  My hope, albeit thin, was that the tab controller  would pick up the view with the binding navigator supplied through the summarydetailpagecontroller.  Unfortunately, that did not work out.  The reason is that the new controller for the view is never called.  Nevertheless, the view with data did show up in the tab, but no way to navigate it or update it.  At least, I see now how easy it is to transplant views.
 
Somehow, I need to get the tabcontroller to inherit from the summarydetailpagecontroller; or, perhaps, create a hybrid of these two calling it a ControlViewTabController, or something like that.  Wacko
 
Time for the weekend.


Posted By: Bill Jensen
Date Posted: 21-Sep-2007 at 5:45pm

It works with a GridView because Ward has implemented a "GridViewToolStripAdapter" (an abstract class in IdeaBlade.Cab.Interface/Miscellaneous) and the concrete class DotNetNavigatorGridViewToolStripAdapter (in IdeaBlade.Cab.UI/Miscellaneous).

This is used by the GridViewPresenters to allow the navigation tool bar to manipulate the view's binding source.
 
Despite the name, there is very little in these classes that is dependent on GridViews  (The main thing that I see is a dependency on the ViewContext being a GridViewContext).
 
I'll talk with Ward about how this is implemented, but I'm afraid this is a case where we've provided a working example of how to do something, but it's up to you to replicate it for a different scenario.
 
Another option:
 
Rather than following this pattern and making the navigation tool strip part of your control view, you might follow my LayoutDemo pattern and create a layout view with a tool strip and a single SmartPartPlaceholder.
 
Its controller (a TabViewController if it's going in a TabWorkspace) would get the binding source from the child view context and hook it up to the navigator.  (Use reflection to see if the child view context implements an interface (call it "IBoundContext").  If so, get the binding source through it and hook it up to the navigator.  If not, hide the navigator. 
 
Then simply make your control view use a special context object that implements IBoundContext and supplies its binding source.
 
I haven't tried this, but is seems like it should work.
 
Bill J.


Posted By: Linguinut
Date Posted: 24-Sep-2007 at 9:55am

Thanks for the direction!  I am working on implementing a new ControlViewToolStripAdapter.  The context thing is a bit cryptic to me but I am making headway.  I am going to try to make the adapter dependent on the ViewContextBase rather than the GridViewContextBase.  I should have something going by the end of the day.  If not, I'll pop in more questions here.

Again, thanks!


Posted By: Linguinut
Date Posted: 24-Sep-2007 at 3:26pm
The following are the items that I have created in an attempt to duplicate the toolbar adapter in a loose control view context:
 
IdeaBlade.Cab.DevEx
  Views
    Base
      DotNetControlViewWithToolBar.cs
IdeaBlade.Cab.Interface
  Miscellaneous
    ControlViewToolStripAdapter.cs
  Views
    Base
      ControlViewContextBase.cs
      IControlViewWithToolbarPresenter.cs
IdeaBlade.Cab.UI
  Views
    Base
      ControlViewContext.cs
      ControlViewWithToolbarHelper.cs
      ControlViewWithToolbarPresenter.cs

    Widget
      BasicControlViewWithToolbarPresenter.cs
 
MyApp
  PageControllers
    ContactsViewTabViewController.cs
  Views
    ContactsView.cs
    ContactsViewPresenter.cs
 
So far, my efforts have resulted in white screens of death in the VS IDE.  Something is not quite right with linkage between the actual view in my app and the helper class in the IB.CAB.UI project.  Not sure if I have learned how this all works, yet.  I'll keep working on it.  I'm sure that I have not thrown the right switch somewhere.
 
More docs on how this stuff all works together would be great.  I think someone said there were some in the works.  Not only would a doc that states what is inherited from what, but the whys and wherefores would be excellent to have, too.
 
Bill


Posted By: Bill Jensen
Date Posted: 24-Sep-2007 at 3:38pm
I agree, this seems like a complex solution to me.  If it gets too deep, you might try the alternative of creating a layout view with a binding manager and a single SmartPartPlaceHolder, then hosting your control view within that.
 
Bill J.


Posted By: Linguinut
Date Posted: 24-Sep-2007 at 4:22pm

Soooo close.

I was going to paste an image here, but the forum has blocked me from uploading.  It states that I do not have sufficient privileges.  Oh, well.
 
What I have gotten is my view loads in the tab detail area of the SearchMasterDetail page.  I can see the binding navigator in full living color!!  Now, I just need to get my designer to quit hollering at me about the helper class.  I'll post more here shortly once I figure out why this class is not getting called properly from the designer.  And, I can get my data to show up.
 
Almost there.


Posted By: Linguinut
Date Posted: 24-Sep-2007 at 5:19pm
Just in case anyone can help, here is the error that I get when attempting to open the ContactsView.cs in Design view:
 
X One or more errors encountered while loading the designer. The errors are listed below. Some errors can be fixed by rebuilding your project, while others may require code changes.

Could not load type 'IdeaBlade.Cab.UI.Views.ControlViewWithToolbarHelper' from assembly 'IdeaBlade.Cab.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.

- Hide     

at IdeaBlade.Cab.DotNet.DotNetControlViewWithToolbar..ctor()
 
I did try the normal rebuild/debugging routines.  The one thing that I did not try was the close/reopen VS thingy.  I will try that and let you know if that worked.  There has been issues in the past where VS didn't renew its cache or something.  Stand by.


Posted By: Linguinut
Date Posted: 24-Sep-2007 at 5:39pm
Yup...the ugly VS cache was rearing up again.  Closing/reopening the solution did the trick.  I got to stop thinking it was my fault and try that first next time.
 
Anyway, now I have the data showing up (because I can now bind some controls); however, the toolbar is inactive.  I think there is a switch in there somewhere, but it is time to go home.  Maybe tomorrow I'll be able to wrap this up.


Posted By: Linguinut
Date Posted: 25-Sep-2007 at 9:45am

I cannot get the toolbar enabled.  I do not know where to throw the switch.  Data is showing up on the view in the tab control.  I can update the record that I am on (both customer and contact).  I just cannot see more than one contact because the navigation is disabled.  Where should I enable the toolbar?



Posted By: Bill Jensen
Date Posted: 25-Sep-2007 at 10:58am
Have you checked that the BindingSource for the ControView is properly assigned to the BindingSource property of the BindingNavigator.
 
Bill J.


Posted By: Linguinut
Date Posted: 25-Sep-2007 at 1:01pm

Ugh!  After all that work yesterday, I think I really screwed up the LIB source projects.  I added a ControlViewWithToolbarPresenterBase class in order to replicate what was done in the GridViewPresenterBase class. For the life of me, I cannot get the ViewContext to behave in the following method of the presenter class:

protected override ControlViewToolStripAdapter SetControlViewToolStripAdapterCore(object pToolStrip)
{
    return new DotNetNavigatorControlViewToolStripAdapter 
         (pToolStrip
 as BindingNavigator, BindingSource, ViewContext);
}
 
It is looking for the type ControlViewContextBase.  It is in the presenter base class.  That type is being returned as ViewContext.  And, it should be available to this presenter.  Yet, it ain't happenin'.
 
Time to take a walk.  Maybe it will all fall into place after I clear my head a little.


Posted By: Bill Jensen
Date Posted: 25-Sep-2007 at 2:03pm
I'd like to help, but I don't quite understand the problem.
 
What do you mean when you say you can't "get the ViewContext to behave"?  Do you get a compile error?  An exception at runtime?
 
Are you calling SetControlViewToolStripAdapterCore() after the context has been set in the presenter?
 
Bill J.


Posted By: Linguinut
Date Posted: 25-Sep-2007 at 2:13pm
The ViewContext is showing up as an IBindingViewContext type rather than the expected type of ControlViewContextBase.  The presenter base class has the following:

///
<summary>Get the ControlView's ViewContext.</summary>
protected new ControlViewContextBase ViewContext {
    get { return (ControlViewContextBase) base.ViewContext; }
}

/// <summary>Get the view's ViewContext.</summary>
IBindingViewContext IControlViewWithToolbarPresenter.ViewContext{ get { return ViewContext; } }

This is setup in the same way as the grid view presenter base class.  I tried to force the type by casting it; however, that did not work.
 
I am not sure if SetControlViewToolStripAdapterCore() is called after setting the context.  I will set some breakpoints to see if the calls are being made in the proper order.
 
 


Posted By: Linguinut
Date Posted: 25-Sep-2007 at 2:34pm
I found an override where one didn't need to be.  It was in the ControlViewWithToolbarPresenter class. 

///
<summary>get the view's bindingviewcontext</summary>
public new ibindingviewcontext viewcontext
{
    get { return (ibindingviewcontext)base.viewcontext; }
}
 
I commented this section out.  Now, I am past that error, but am now experiencing another.  A similar error so I will review all of the various pieces again and see what I overlooked.  It is not easy converting from the grid view to the control view.


Posted By: Linguinut
Date Posted: 25-Sep-2007 at 3:20pm

Unable to cast object of type 'IdeaBlade.Cab.UI.ControlViewContext' to type 'IdeaBlade.Cab.Interface.ControlViewContextBase'.

This is being thrown on:
/// <summary>Get the ControlView's ViewContext.</summary>
protected new ControlViewContextBase ViewContext {
    get { return (ControlViewContextBase) base.ViewContext; }
}


Posted By: Bill Jensen
Date Posted: 25-Sep-2007 at 5:01pm
So...
 
does IdeaBlade.Cab.ControlViewContext inherit from IdeaBlade.Cab.ControlViewContextBase?
 
Neither of these are defined in standard IdeaBlade.Cab.  The ControlView is built using BindingViewContext.
 
What are you adding in ControlViewContext (and CVCBase) that isn't present in BindingViewContext?
 
Bill J.


Posted By: Linguinut
Date Posted: 25-Sep-2007 at 5:18pm
It is very difficult to present to the forum all of the intricacies of this project.  As a result, I have obviously not provided enough information about what I am doing.  Sorry about that.
 
I didn't have any kind of support for the toolstrip in the BindingViewContext, so I created a new one--ControlViewContext.  I threw a few things in there to get the ball rolling.  It is possible that I didn't need to do that.  I am attempting to get this current casting issue resolved and it may include rewritting some of those classes.
 
As I was finishing this response up, I did notice that ControlViewContext was inheriting directly from BindingViewContextBase.  I changed that to ControlViewContextBase.  Building now.  Will test shortly.


Posted By: Linguinut
Date Posted: 25-Sep-2007 at 5:24pm
Ok.  The test was partially successful.  I was able to get past the casting problem.  Now, I am still trying to figure out how to get the toolbar to be enabled.  It has got to be related to SetControlViewToolStripAdapterCore() somehow.


Posted By: Bill Jensen
Date Posted: 25-Sep-2007 at 6:23pm

As I mentioned earlier, ensure that the BindingSource for your ControlView is properly assigned to the BindingNavigator.



Posted By: Linguinut
Date Posted: 25-Sep-2007 at 8:49pm
From the ContactsView class:
 
[InjectionMethod]
public void InjectPresenter([CreateNew] DotNetControlViewWithToolbarPresenter<IBindingView> pPresenter)
{
    SetPresenter(pPresenter, mNavigator, mControlBindingManager);
}
 
Is this the right way to do this?


Posted By: Linguinut
Date Posted: 26-Sep-2007 at 11:05am

The culprit was in the new ControlViewWithToolbarPresenterBase.cs class.  I had the following:

/// <summary>ViewContext was set and is presumed ready with values.</summary>
protected override void OnViewContextSet() {
    base.OnViewContextSet();
    SetBindingManagerBindingSource();
    SetControlViewToolStripAdapter();
}
 
In the GridViewContextBase there was a slough of stuff that inaugurated the GridView.  Inside of one of the methods was a call like this:
 
GridViewToolStripAdapter.Configure();
 
Aha!!  I added the call to the OnViewContextSet() above.  Now, the data shows up properly with navigation to the additional entities.  Good stuff!!!
 
Alas!  There is always a cloud with every silver lining.  I assumed (ya, bad idea) that the add, delete and save buttons would appear in the toolbar, but they do not.  Another switch is hiding in there somewhere.  Now, where is that thing?


Posted By: Linguinut
Date Posted: 26-Sep-2007 at 1:14pm
Along the way, I found the DevExPageView.  I created a new ContactView2 and inherited from this control.  I passed it to the GeneralTabViewController and got the error that ContactView2 could not be converted to IBindingView.  Bummer.  That would have saved a lot of work...it has the add/edit/delete and alert messaging...sure would be nice.  Is there a way to do that, maybe?


Posted By: Linguinut
Date Posted: 26-Sep-2007 at 2:04pm
I found this method:  AddToControlViewToolStrip() in the DotNetNavigatorControlViewToolStripAdapter (adapted from the DotNetGridViewToolStripAdapter).  It has the AddEditButton, AddAddNewButton and AddDeleteButton methods that I want, but how do I get them to fire?
 
This is quite odd.  The DotNetNavigatorControlViewToolStripAdapter inherits from ControlViewToolStripAdapter in which the following is declared:

///
<summary>Add to the ControlViewToolStrip <see cref="UIExtensionSite"/>.</summary>
protected virtual void AddToControlViewToolStrip() {
}
 
In that same class is the Configure() method which has as one of its calls, AddToControlViewToolStrip().  That method is defined (with the add button methods) in DotNetNavigatorControlViewToolStripAdapter, not in ControlViewToolStripAdapter.  Shouldn't these add button methods be in that class rather than the class that is inheriting from it?  In the event that I don't want them implemented, I could override in the class that is inheriting from it.  Well, I may not have this square in my head, but if someone else could look at this and let me know what to do or how to think about it, I would really appreciate it.  The same structure is found in Cabana with the DotNetNavigatorGridViewToolStripAdapter (IdeaBlade.Cab.UI) and the GridViewToolStripAdapter (IdeaBlade.Cab.Interface).
 
Thanks!!
Bill


Posted By: Bill Jensen
Date Posted: 26-Sep-2007 at 4:20pm

Sorry not to post sooner today--I've been out for some appointments and errands.

You've got a couple of things going in this thread which has become rather long.  At some point we should close this thread and start a couple of new ones.
 
Anyway, to address your most recent post:
 
First, the tool strip adapter is implemented as a classic template pattern:
 
GridViewToolStripAdapter is an abstract template class that delegates its implementation details to a concrete implementation class.  It always looks the same to its client class, GridView (or more precisely, GridViewPresenterBase).  In this case, Ward has provided only one concrete implementation:  DotNetGridViewToolStripAdapter.
 
Second, the template pattern is extremely common and occurs again:
 
GridViewPresenterBase is itself an abstract template that delegates its implementation to concrete classes, two in this case:  DotNetGridViewPresenter and DevExGridViewPresenter. 
 
Once the view context is set, the OnContextSet() method configures the grid view.  One of the steps is to invoke SetGridViewToolStripAdapter() that delegates to the concrete implementation of SetGridViewToolStripAdapterCore() which creates a new DotNetGridViewToolStripAdapter, passing the tool strip object itself, the binding source and the view context.
 
Immediately after calling SetGridViewToolStripAdapter(), GridViewPresenterBase calls its Configure() method.  Among other things, Configure() invokes AddToGridViewToolStrip() which is again delegated to the concrete implementation.
 
Your ControlView-based versions of these classes should work in exactly the the same way.
 
N.B.: The GridViewToolStripAdapter and DotNetGridViewToolStripAdapter classes have "GridView" appearing all over the place.  On closer examination however, almost all of these are just class, member and variable names. 
 
The only real dependency is on the view context being a GridViewContextBase and even that is only used to provide three items:
 
The binding source (actually available from the base BindingViewContextBase class)
 
The GridViewToolStripVisible flag.
and
The GridViewToolStripChanged event.
 
These last two could be made optional by moving them to an interface, IGridViewToolStripContext, then having GridViewToolStripAdapter check if the view context implements this interface and hook them up if so.
 
Once that's done, the dependency on GridView (and ControlView, in your case) could be eliminated and it becomes possible to add a tool strip to any binding view.  If there were a BindingViewPresenterBase class (there isn't) we could move the logic there but for now, we can just leave it in our specific base presenter classes.
 
This kind of refactoring is constant in a framework like Cabana.  We start with specific implementations for initial use cases (i.e., GridView tool strips in this case), then, rather than duplicating code, refactor to a more abstract implementation to cover more use cases.  In the process we eliminate dependencies and increase reusability.
 
My battery is going dead...gotta post this.
 
Hope this helps.
 
Bill J.


Posted By: Linguinut
Date Posted: 27-Sep-2007 at 5:33am
Hey Bill,
 
No problem with your posting frequency.  I am glad whenever you can offer help.  I do wish that there were more of us out here, though.
 
This is getting to be a long thread; however, it is all related to my desire to create the control view widget with a toolbar.  I am at the very final stages of this journey.
 
Thanks a bunch for the bird's eye overview of the adapter classes.  I will work through this for understanding.  Unfortunately, the classic template is a relatively new animal for me.  I am still doing a lot of catch-up reading to get more acquainted.
 
Thanks, again.  I'll update here when I get more answers or have more questions regarding this.
 
Bill


Posted By: Linguinut
Date Posted: 27-Sep-2007 at 8:15am
Originally posted by Bill Jensen

Immediately after calling SetGridViewToolStripAdapter(), GridViewPresenterBase calls its Configure() method.  Among other things, Configure() invokes AddToGridViewToolStrip() which is again delegated to the concrete implementation.

 
Slowly wrapping my brain around this. 
 
The ControlViewToolStripAdapter has a protected virtual method defined called AddToControlViewToolStrip.  The class DotNetNavigatorControlViewToolStripAdapter is derived from ControlViewToolStripAdapter; therefore, has the implementation of the AddToControlViewToolStrip method.  When a call is made to ControlViewToolStripAdapter.Configure, the method AddToControlViewToolStrip is called.  This is where I get confused.  The abstract class then calls the concrete class to run the method defined there?  Is that right?  Does the protected virtual designation make a difference over the protected abstract designation?
 
Thanks.


Posted By: Linguinut
Date Posted: 27-Sep-2007 at 10:12am
I can walk the code.  Btw, I changed the virtual tag to abstract, then back to virtual--the code does the same thing either way.  The call is being made to the concrete class (as expected).  The buttons are being built.  But they are not showing up on the toolbar.  The UIExtensionSite  looks like it is being registered properly.  The buttons are being added to that defined site.  Nothing is showing up.  This remains a mystery.


Posted By: Bill Jensen
Date Posted: 27-Sep-2007 at 10:19am
A quick refresher on object-oriented 101, C# style:
 
The ControlViewToolStripAdapter has a protected virtual method defined called AddToControlViewToolStrip. 
 
Correct.  It has an empty body.  The virtual declaration indicates that a child class may provide a non-empty implementation.  The protected modifier merely restricts the visibility to the base and child classes.  A virtual method can be public or internal, but private virtual doesn't make any sense.
 
The class DotNetNavigatorControlViewToolStripAdapter is derived from ControlViewToolStripAdapter; therefore, has the implementation of the AddToControlViewToolStrip method.
 
Correct, though it doesn't have to provide an implementation, since an empty implementation is provided in the base class.  If it were marked abstract in the base class, the child class would be required provide an implementation.
 
When a call is made to ControlViewToolStripAdapter.Configure, the method AddToControlViewToolStrip is called.  This is where I get confused.  The abstract class then calls the concrete class to run the method defined there?  Is that right? 
 
Yes, that's the meaning of the override modifer on a method; when the method is invoked, the implementation in the overriding method is called, even if the invoker thinks it is holding a reference to an instance of the base class.  
 
Does the protected virtual designation make a difference over the protected abstract designation?
 
If the child implementation were marked new (instead of override), then the child method will be invoked if the invoker holds a reference to an instance of the child class, but the base class method will be invoked if it is called on a reference to the base class.
 
Does this clarify things?
 
Bill J.
 


Posted By: Linguinut
Date Posted: 27-Sep-2007 at 10:54am
I created a DotNet Grid View and added it to the customer tab controller.  No toolbar is displayed, so I cannot even tell if the buttons will show up.
 
Bill, can you verify that the add/edit/delete buttons, in fact, do show up on a DotNet Grid View?
 
Thanks!


Posted By: Linguinut
Date Posted: 27-Sep-2007 at 10:55am
I much appreciate the quick refresher.  I wanted to make sure that my thinking was straight on these issues.  Thanks.
 
Btw, I am going to start a new thread regarding the toolbar buttons.


Posted By: Bill Jensen
Date Posted: 27-Sep-2007 at 11:12am

In the DotNetGridViewToolStripAdapter (and presumably your ControlView version), the method AddButtonToGridViewToolStrip() contains the code:

if ( pHideIfNoCommandHandler ) {

CabFns.ResetStatusIfNoHandlers(WorkItem, commandName, CommandStatus.Unavailable);

Basically this hides the button if its attached command doesn't have a handler registered.
 
The ToolStripAdapter (and in fact the presenter that owns it) doesn't care what happens when a button is clicked--it merely sets up a command (with a name that includes the unique ViewId)  and fires it.
 
The handler for the command must be registered somewhere.  It remains a mystery to me where this is done for the detail grid view case.  However, the MasterDetailTabViewController contains this function:

/// <summary>Register CommandHandler for a Command on the detail view.</summary>

/// <param name="pCommandRootName">The root name of the CommandName to make (e.g., "Edit").</param>

/// <param name="pHandler">CommandHandler of this command.</param>

protected void RegisterDetailCommandHandler(string pCommandRootName, EventHandler pHandler) {

string commandName = mDetailViewContext.MakeViewSpecificId(pCommandRootName);

CabFns.RegisterCommandHandler(WorkItem, commandName, pHandler);

}

I can't find any invocations of this method, but at least it shows you how to register a command handler.  You'll need to register handlers for the button events (probably in your ContactViewTabController).

I'll try to get some more information out of Ward.
 
Bill J.


Posted By: Linguinut
Date Posted: 27-Sep-2007 at 12:05pm
Here is the method in the DotNetNavigatorControlViewToolStripAdapter:

protected
void AddButtonToControlViewToolStrip(ToolStripButton pButton, string pCommandRootName, bool pHideIfNoCommandHandler) {
  string commandName = ViewContext.MakeViewSpecificId(pCommandRootName);
  ControlViewToolStripSite.Add(pButton);

  CabWinFormFns.AddCommandToButton(WorkItem, pButton, commandName);
  if
( pHideIfNoCommandHandler ) {
    CabFns.ResetStatusIfNoHandlers(WorkItem, commandName, CommandStatus.Unavailable);
  }
}
 
What if I added the following into the above code?
 
CabFns.RegisterCommandHandler(WorkItem, commandName, pButton.Click);
 
All of the ingredients I need are right there while the button is cooking.  I am not sure how I would do this in the tab controller.
 
Bill
 
Note: pButton.Click cannot be used as the EventHandler passed in the argument.  The eventhandler must be presented another way.


Posted By: Linguinut
Date Posted: 27-Sep-2007 at 1:35pm
From what I can tell, I would have to implement the actual add/save/delete calls (EntityManager.SaveAll(), or something like that).  This kind of thing should already be wrapped up above this toolbar somewhere and accessible to it.  I do not want to rewrite any of the code found in the MasterDetailTabViewController.  Shouldn't it have "bubbled up" someplace else, already?  Well, I hope Ward can come to the rescue and point the way on this.  I do want to duplicate code unnecessarily.  If the wheel has already been created...


Posted By: Bill Jensen
Date Posted: 27-Sep-2007 at 1:55pm
Sorry, you have to provide the handlers to add, edit or delete objects.  In MasterDetailTabViewController (in IdeaBlade.Cab.UI), look at the method
 
ConfigureMasterViewContext()
 
You'll need to create handlers and register commands in much the same way in your ContactViewTabViewController.  Just walk thru the code to see how it's done.
 
The point of the command pattern is to decouple the source of the command's firing (button, menu item) from the actual command processing.  The view controller is where you "know" about how to create, edit and delete elements of your data mode.  You don't want to couple the general-purpose presenter or the ToolStripAdapter to this information.
 
Bill J.


Posted By: Linguinut
Date Posted: 27-Sep-2007 at 2:10pm
I should create a new ControlViewTabViewController in the IdeaBlade.Cab.UI project under the TabViewController folder.  When I add a new control view to a tab controller, I would just add the view using this controller.  What I am trying not to do is have to create all of that add/edit/delete code every time I add a new view.
 
Please let me know if there are any gotchas for doing it this way.


Posted By: Bill Jensen
Date Posted: 27-Sep-2007 at 3:45pm
Yeah, that sounds reasonable.  It'll probably be generic <boundType>.  Be sure to follow the template pattern so a specific TabViewController can override the Add, Delete and Edit methods.
 
Bill J.


Posted By: Linguinut
Date Posted: 28-Sep-2007 at 4:53pm
Thanks for all of your help, Bill.  I am going to end this thread.  It is a bit long.  And, I think I can pursue other questions separately, now.  The new widget control view works quite well.


Posted By: orcities
Date Posted: 29-Sep-2007 at 10:32am
Can you supply your final findings and paths to final product. This thread was rather long and hard to keep track of what exactly was going on.
 
 


Posted By: Linguinut
Date Posted: 29-Sep-2007 at 10:36am
Hey Dan,
 
Certainly.  I am leaving for the day, so Monday I will try to put something together as a summary of this widget view creation.
 
Have a good weekend!
Bill



Print Page | Close Window