Tech Off Thread

11 posts

So, how are you implementing MDI in WPF?

Back to Forum: Tech Off
  • User profile image
    DCMonkey

    We've had various discussions about MDI and MDI-like UI and WPF here and in the Coffeehouse before, and I've seem some mention they've done it using UserControls as your forms/child windows. I'm curious about how you all are managing those UserControls. There are a couple of ways I could see to do it:

    1) Just add them as new tabs in a TabControl. Easy, but it requires a 1-to-1 correspondence between tabs and UserControls, which may not always be what you want. I suppose you could hide the tabs though and provide an alternate UI for switching between them.

    2) Write a custom ItemsControl (or Selector) with an item host that just stacks the items right on top of each other (ie: A single cell grid) and manage the visibility or ZIndex of the items. This might make it easier to implement some fancy switching behavior. A separate control would manipulate this ItemsControl to display the desired UserControl.

    3) Manage the collection or collections of UserControls yourself and assign the active UserControl to the Content property of a single ContentControl. Strangely enough, even though the TabControl is an ItemsControl it appears to use a method similar to this to display the content of a selected tab item rather than something like method #2.

    How are you tackling this?

  • User profile image
    figuerres

    or just design an app that does not use an MDI.

    really.

    you can, and 99.999% of time I think we should.

    what do you see as needed an MDI ??

  • User profile image
    DCMonkey

    figuerres said:
    or just design an app that does not use an MDI.

    really.

    you can, and 99.999% of time I think we should.

    what do you see as needed an MDI ??
    Theoretical CRM App:

    Dashboard "Home Screen"
    Contact lookup
    Contact Edit
    Sales Opportunity Lookup
    Sales Opportunity Edit
    Report Selection screen
    etc
    etc
    etc

    The alternative is a bunch of top level windows and dialog boxes and leaving the user to manage those. I don't want to do that.  And WPF's Navigation support is too limiting I think at this point.

    I don't even want actual MDI as implemented  in Win32/WinForms anymore (there is an example out there where someone implemented this using a variation of method #2). Just a way to open and switch between screens/forms contained in a single window. But everyone else calls that "MDI" so I am too.

  • User profile image
    figuerres

    DCMonkey said:
    figuerres said:
    *snip*
    Theoretical CRM App:

    Dashboard "Home Screen"
    Contact lookup
    Contact Edit
    Sales Opportunity Lookup
    Sales Opportunity Edit
    Report Selection screen
    etc
    etc
    etc

    The alternative is a bunch of top level windows and dialog boxes and leaving the user to manage those. I don't want to do that.  And WPF's Navigation support is too limiting I think at this point.

    I don't even want actual MDI as implemented  in Win32/WinForms anymore (there is an example out there where someone implemented this using a variation of method #2). Just a way to open and switch between screens/forms contained in a single window. But everyone else calls that "MDI" so I am too.

    well "MDI" is multiple open child windows in a parent window.

    so you are not looking for "MDI"  and if someone else calls it MDI they just got it wrong.

    one thing you can do, I have used a version of this in an app is...

    setup an Interface and a parent container, then have each "Task" or "Function" be a user control that impliments that Interface.

    so you have an app "frame" with a big empty panel.

    when a menu item or button bar button etc... need to "open" / "load" the task you create an instance of the user control and dock it in the panel.

    you can keep a stack of ITaskPanel (if that's the name of the interface)

    and when the user "closes" the one displayed you pop it off the stack and show the new top of stack.  that's if you need to chain forms like a => b => c and then back .

    or for single tasks the stack can hold the "default Home" control that you return to.

    that's one model that works very well.

     

  • User profile image
    DCMonkey

    figuerres said:
    DCMonkey said:
    *snip*

    well "MDI" is multiple open child windows in a parent window.

    so you are not looking for "MDI"  and if someone else calls it MDI they just got it wrong.

    one thing you can do, I have used a version of this in an app is...

    setup an Interface and a parent container, then have each "Task" or "Function" be a user control that impliments that Interface.

    so you have an app "frame" with a big empty panel.

    when a menu item or button bar button etc... need to "open" / "load" the task you create an instance of the user control and dock it in the panel.

    you can keep a stack of ITaskPanel (if that's the name of the interface)

    and when the user "closes" the one displayed you pop it off the stack and show the new top of stack.  that's if you need to chain forms like a => b => c and then back .

    or for single tasks the stack can hold the "default Home" control that you return to.

    that's one model that works very well.

     

    I should have never mentioned MDI, I actually agree with your point about its specific meaning and have argued that here before. I was just too lazy to come up with a better term for it. I actually do mean a UI like you describe.

    My question was more about how others have managed those UserControls. I've already done what you describe using an ItemsControl with a Grid with 1 row and 1 column as Items Host, bound to a collection of my UserControls. This would work as a LIFO stack like you describe but I would also like to be able to switch between "open" UserControls, hence my suggested method #2. I was curious if others went the same or a different route and what advantages or disadvantages a particular method might have that I might be missing.

  • User profile image
    figuerres

    DCMonkey said:
    figuerres said:
    *snip*
    I should have never mentioned MDI, I actually agree with your point about its specific meaning and have argued that here before. I was just too lazy to come up with a better term for it. I actually do mean a UI like you describe.

    My question was more about how others have managed those UserControls. I've already done what you describe using an ItemsControl with a Grid with 1 row and 1 column as Items Host, bound to a collection of my UserControls. This would work as a LIFO stack like you describe but I would also like to be able to switch between "open" UserControls, hence my suggested method #2. I was curious if others went the same or a different route and what advantages or disadvantages a particular method might have that I might be missing.
    well  not to say that there may not be a need to switch but first I'd make sure I had a good design, many times adding a label or some other control can tell the user the info that wuld have comne from the other "page" so to speak.

    but *IF* you need a back and forth process then it sounds like a case for a "Wizzard" or a "Tab Pages" UI

  • User profile image
    nightski

    I would take a look at the prism reference implementation by Microsoft.  Our solution was before prism came out, but essentially our architecture is very similar.  We utilize the MVP pattern and have the concept of a view host.  Basically in XAML you can specify where content should go by placing viewhosts.  Presenters can then inject a view into the view host dynamically.  A view host can itself be an items control that can host multiple views.  Also view hosts can be nested so that you can have a distinct presenter driving each particular view.

    When you utilize this type of architecture doing something like you mentioned is trivial.  To open up a view all you do is instantiate a new copy of the presenter and specify the view host it should inject its view into.  This could be a tab itemscontrol.  Or it could be an itemscontrol that uses a custom template to give views a more MDI like feel within the container.

    It is completely customizable.  Views are completely independent of Presenters and vice versa.  The only contract is in the data binding.

    Lastly we have a separate service that takes care of navigation services.  So when the presenter injects its view, it does so through the navigation service.  This service takes care of remember history and so forth so that the user can go back & forth among the views.

    The nice thing about this architecture is that the actual size of the supporting libraries are very minimal and very testable.  This follows good agile principles.

  • User profile image
    chuck p

    I guess I'll buy a 3rd party control that does it.  My app has about 20 data entry forms and 60 reports.  Doing some kind of goofy Outlook or multiple tab interface would be torturing the users.

  • User profile image
    DCMonkey

    chuck p said:
    I guess I'll buy a 3rd party control that does it.  My app has about 20 data entry forms and 60 reports.  Doing some kind of goofy Outlook or multiple tab interface would be torturing the users.
    Although it still probably wouldn't help your extreme example, I think that maybe Windows 7's new taskbar could make the basic SDI one window per form model the preferrable arrangement again.

  • User profile image
    AndyC

    chuck p said:
    I guess I'll buy a 3rd party control that does it.  My app has about 20 data entry forms and 60 reports.  Doing some kind of goofy Outlook or multiple tab interface would be torturing the users.
    Does the user really need access to all 60 reports or all 20 data access forms simultaneously? Is there a better way of presenting the data? Is there a typical workflow that can be exploited to simplify the interface?

    One of the real problems with MDI (and MDI style interfaces) is that it is all to easy to just expose all available information to the user and expect them to deal with the management, rather than to analyse how that information could be better presented.

  • User profile image
    figuerres

    AndyC said:
    chuck p said:
    *snip*
    Does the user really need access to all 60 reports or all 20 data access forms simultaneously? Is there a better way of presenting the data? Is there a typical workflow that can be exploited to simplify the interface?

    One of the real problems with MDI (and MDI style interfaces) is that it is all to easy to just expose all available information to the user and expect them to deal with the management, rather than to analyse how that information could be better presented.
    Yeah, think of two cases, the "Pro" who knows what all the forms and reports are for, sure he might want to open stuff at random.

    but what about the "new user" or the "occasional user"

    they want / need to get a task done.  where do they start?  how does your app help them get from 1 to 5 w/o hunting down 20 things?

    even a pro might like a guided flow thru some forms....

    now this does not mean it has to look like outlook.  it does mean working out what users "tasks" and "work flows" are and then having the app reflect the flows and offer a basic level of structure.
    you can still have menu items that go to all the forms..... but most users should not need to look at 80 menu items just to print a report.

Comments closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums, or Contact Us and let us know.