Click here to Skip to main content
Email Password   helpLost your password?

Introduction

This article assumes that you are familiar with CAB (Composite UI Application Block), SCSF (Smart Client Software Factory), Guidance Packages and WPF (Windows Presentation Foundation). Although Microsoft Patterns & Practices team planned to provide support for WPF in April 2007 SCSF releases, this article demonstrates how to develop CAB workspaces that can use any technologies WITHOUT ANY WRAPPER WINDOWS.

Some community sites offer entire CAB in WPF technologies. But I would not recommend using those patterns since those do not comply with any standards. Also, CAB foundation must provide support for smart clients developed in .NET Framework 2.0 as well.

As you know, CAB is best known for its loosely coupled architectures, so why don't you architect your smart client also to couple loosely with WPF Windows & controls in CAB 2.0 environment?

CAB Workspaces

CAB provides numerous patterns such as WorkItems, Workspaces, Controllers, Services, Commands, Actions, Event Broker, Modules, Dynamic Module Loader, Smart Parts, MVP, MVC patterns, Guidance Automations, Builder strategies, Profile Catalog, Smart web references, Entity translators, Layout principles and Shell. Among these patterns, Workspaces pattern is taken by this article.

During the Smart client UI design, Workspaces is the important pattern. This article is going to walkthrough how to design an XAML based window workspace using WPF or other technologies. In this loosely coupled architecture, Workspaces is a collection maintained in the WorkItem object. You can create the workspace anywhere and use it anywhere.

There are two types of workspaces. Composable and Non-Composable. Composable workspaces are combined with some controls for example tab controls. Non-Composables are not combined with such controls.

Every workspace in CAB should be derived from Workspace/IWorkspace class found in CompositeUI.SmartParts namespace.

public abstract class Workspace<TSmartPart, TSmartPartInfo> : IWorkspace 

This abstract class designed in an excellent way that we can implement any types since it provides Generic types. (Please try to understand "Generics" before you continue this article – if you do not know.)

So, while implementing workspaces, you can use any types depending upon your technology needs.

The default CAB provides 2.0 window workspace like this:

public class WindowWorkspace : Workspace<Control, WindowSmartPartInfo> 

where Control is a 2.0 Control and WindowSmartpartInfo provides additional details to construct and shows the 2.0 window.

We are going to implement like this in order to provide WPF support:

public class XamlWindowWorkspace : Workspace<UIElement, XamlWindowSmartPartInfo> 

where UIElement is an equivalent to Control in WPF and XamlWindowSmartpartInfo provides additional information to construct the XAML based WPF Windows.

Interop with 2.0 Shell

if (info.Modal == true)
{
SetWindowLocation(window, info);
//Set parent form, Handle can be null
new WindowInteropHelper(window).Owner = ownerForm.Handle;
// Show dialog.
window.ShowDialog();
} 

During the API call ShowDialog(), we need to attach the 2.0 shell window handle to WPF window. In order to do this, we need to use the WindowInteropHelper class to get 3.0 window handle. Please note that, here we are just getting a handle of the XAML window. We are not using any wrapper windows to host XAML windows on 2.0 Windows.

XAML Window Attributes

To apply the additional XAML window attributes during the WPF windows launch the XamlWindowSmartPartInfo class can be used. It provides the window attributes such as Modal flag, Startup location, Window state, Window style, Width, Height, Top most flag, etc.

Workspace Constant

You need to declare a new workspace constant in Infrastructure.Interface\Constants\WorkspaceNames.cs in order to use other modules as below.

//Newly Added 
public const string XamlWindowWorkspace = "XamlWindowWorkspace"; 

Workspace Creation

This XAML window workspace needs to be created along with the other default workspaces and added into workspaces collections as below:

// Add XAML window workspace to be used for launching XAML based modal 
// or modeless windows 
XamlWindowWorkspace xamlWindowWsp = new XamlWindowWorkspace(_shellLayout.ParentForm); 
_rootWorkItem.Workspaces.Add(xamlWindowWsp, WorkspaceNames.XamlWindowWorkspace);

Sample Usage

The following sample demonstrates how to use this workspace:

//Get 3.0 modal workspace from Root WorkItem 
IWorkspace wsp = this._presenter.WorkItem.Workspaces.Get("XamlWindowWorkspace"); 

//Add a new 3.0 Smart part 
Forms30View forms30View = this._presenter.WorkItem.SmartParts.AddNew<Forms30View>(); 

//Create extra details to launch window 
XamlWindowSmartPartInfo smartPartInfo = new XamlWindowSmartPartInfo(); 
smartPartInfo.Modal = true; 
smartPartInfo.Title = " I am 3.0 Xaml Modal Window & View"; 

//Launch modal dialog 
wsp.Show(forms30View, smartPartInfo); 

Guidance Package Changes

During the guidance package design, make the following changes in order to use this workspace by developers in addition to the default Microsoft's guidance package.

Two new files need to be added as below:

Changes are in:

Conclusion

Do not implement the entire CAB in 3.0 as its architecture itself provides a way to plug your workspaces in a loosely coupled manner. Depending upon your business needs, implement the workspaces in any technologies as demonstrated in this article.

History

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralView not disposed when window is closed !
rjknis
0:58 30 Apr '08  
How do i ensure that the view will be completely disposed on closing the xamlwindowworkspace ? It's showing an error while closing the main window, in View1.xaml.Generatedcode.cs, Dispose() method:

if (_WPFUIElementAdapter != null)
{
System.Windows.Forms.Control host = _WPFUIElementAdapter.Wrap(this); // Error: Specified element is already the logical child of another element. Disconnect it first.

if (!host.Disposing)
{
host.Dispose();
}
_WPFUIElementAdapter = null;
}

I want to dispose the presenter and view, when the window is closed. How do i achieve this ?
GeneralRe: View not disposed when window is closed !
Ethan_S
2:52 11 Oct '08  
Hi I'm facing the same problems. Anyone have a solution to this?

Kr,
Ethan
GeneralError while adding WindowWorkspace class in Interface.Library.UI
seresha
2:56 6 Jul '07  

Thats a nice discussion with Kent. Infact I started my work on SCSF applications using Kent's Bank Teller. But still making some changes to my application based on requirements that I came across this article.

I do have an issue when I tried to implement the code of XAMLWindowWorkspace. Do let me know where I need to make changes..

1. The type 'Microsoft.Practices.CompositeUI.SmartParts.Workspace`2<T0,T1>' is defined in an assembly that is not referenced. You must add a reference to assembly 'Microsoft.Practices.CompositeUI, Version=1.0.51205.0, Culture=neutral, PublicKeyToken=null'.     D:\Projects\MyApplication\Source\Infrastructure\Infrastructure.Library\UI\WindowWorkspace.cs     23     18     Infrastructure.Library

2. The type 'Microsoft.Practices.CompositeUI.SmartParts.SmartPartInfo' is defined in an assembly that is not referenced. You must add a reference to assembly 'Microsoft.Practices.CompositeUI, Version=1.0.51205.0, Culture=neutral, PublicKeyToken=null'.     D:\Projects\MyApplication\Source\Infrastructure\Infrastructure.Library\UI\WindowSmartpartInfo.cs     20     18     Infrastructure.Library

3.The type or namespace name 'UI' does not exist in the namespace 'Mobile.Infrastructure.Library' (are you missing an assembly reference?)     D:\Projects\MyApplication\Source\Infrastructure\Infrastructure.Layout\Module.cs     5     37     Infrastructure.Layout


I am surprised of Version number (51205) but all of the dll including of XAMLWindowWorkspace support 50727.

do let me know what could be the reason for each error and how can i troubleshoot it.

Is there any cross reference happened....

Thanks in advance..

GeneralRe: Error while adding WindowWorkspace class in Interface.Library.UI
Venkatakarthikeyan Natarajamoorthy
12:40 6 Jul '07  
You have assembly version mismatch problem. Open all your assemblies (one by one) those having reference of CompositeUI.dll using MSIL Disassembler (ILDASM) utility (it can be found under Start -> Microsoft .NET framework SDK -> Tools ). Check the version details of CompositeUI. All of them should refer the same version of CompositeUI. If you find different version, go to the project and change reference)


Venkat Nataraj

Generalbuild problem
!Bug
14:45 7 Apr '07  
Hi,

I'm very interested in what you've accomplished here,
I have the following build issue with the sources I downloaded:

Error 2 Argument '1': cannot convert from 'System.Windows.Controls.UserControl' to 'System.Windows.Forms.Control' D:\temp\downloads\CABWPFDemo\ModuleWPF\ModuleWPF\Views\WPFView.cs 81 41 ModuleWPF (Source\ModuleWPF\ModuleWPF)

(this happends on line 81 on WPFView.cs and indeed uc1 is a usercontrol

I tried the various casting stuff but the problem seems more inherent,
could you please assist?
thanx,
--tzurs
GeneralRe: build problem
Venkatakarthikeyan Natarajamoorthy
16:59 7 Apr '07  
This build error is not in my code which I uploaded here. Can you elobarate what you are trying to do? Based on the error which you have stated here, you are trying to add WPF (3.0) control where it is looking for 2.0 control. Xaml controls are entirely different than 2.0 controls. You cant type cast since it has different base classes hierarchy.

Please explain in detail about your problem.

Venkatakarthikeyan Natarajamoorthy

GeneralRe: build problem
!Bug
14:57 8 Apr '07  
sorry about that!
I had probably mistaken your sources with another xaml cab sample,
thanx!
--tzurs
QuestionQuestions
Kent Boogaart
23:12 23 Mar '07  
Hi, thanks for the article. Some questions:

1. What does your code achieve that the code here (http://www.codeplex.com/wpfcab[^]) does not? As far as I can tell, your window workspace is pretty much the same as mine except it handles Winforms 2 windows as well as WPF windows. Am I right?

2. How is this a complete solution for writing WPF applications with CAB? How do you do things analagous to zone workspaces, deck workspaces, tab workspaces? How do you handle CAB visualizers? etc.

I will probably have follow-up questions once you have answered the above.

Thanks,
Kent
AnswerRe: Questions
Venkatakarthikeyan Natarajamoorthy
12:41 26 Mar '07  
Hi, Here are the answers for your questions:

1. I gone through your code today. Your code doe not comply with Microsoft's patterns & practices since it does supports ONLY WPF technologies. Please note that CAB patterns is a framework to develop smart clients to host any parts and NOT restricted to any technologies.

2. Lot more differences between your code and my code as below:
i) Your code does not support any controls other than WPF. But my code comply with Microsoft CAB standards and you can plug any controls in this framework. This sample demonstrate a XAML window workspace - how to plug.
ii) Your WindowWorkspace is hanging alone. Yes, your window workspace does not have any parent window (Or Desktop window is a parent). Please look at your method - GetOrCreateWindow(). You must provide Shell's handle as I explained in my article (without any wrapper window to gain performance). FYI - You can use tools like Spy++ to view the window hierarchy.
iii) CAB Workspace means - it supports collections of smart parts. In other way, it knows how to render more than one smart parts. Your WindowWorkspace does not support more than one smart part. That means your WindowWorkspace is not a workspace at all. It is just a window to show one control. Rather my code is a real CAB workspace and it provides support for more than one smart parts as like other workspaces
iv) You do not have any dispose logic while removing smart parts in the workspace's smart parts collections.
v) WindowSmartPartInfo class members are not having any default values. It is against to the CAB SmartPartInfo architecture.

The list may grow if someone else look at your sources.

3. If you look at the Microsoft CAB team's roadmap -

http://www.codeplex.com/smartclient[^]
http://blogs.msdn.com/blaine/[^]

Priority 1
WPF Interoperability
- Demonstrate how a Windows Forms Application can host Windows Presentation Foundation Parts
- Create a new View/Presenter recipe for WPF views

Unlike you stated at your community site, Microsoft's SCSF team is going to provide support for only to adopt the WPF/WF technologies in the form of recipes, guidance and interops. THEY ARE NOT GOING TO BUILD ENTIRE CAB IN WPF.

Are you going to write one more CAB to support WF? In future, every time do we need to write CAB for every .net's new release? Microsoft never re-implement CAB in WPF. Because CAB is not just a visual element hosting environment. Its more than that. It is a framework - it is a Design Patterns to adopt any technologies.

4. Have you seen Infragistics CAB libraries?

Please look at here: http://www.infragistics.com/hot/cab.aspx[^]
They built before you and their library is exactly like what you did. They re-implemented CompositeUI.Winforms project alone to plug their special controls into CAB envirorment. It does not means that they are not allowing any other controls.

5. Answer to your second question:
using the IWorkspace/Workspace interface generics parameters, you can write any workspaces that hosts any technology parts. You can see some sample customization by Microsoft at the folder: Infrastructure.Library/UI. You can customize or implement additional workspaces here based on your business needs. (FYI - You can also write workspaces using Active-X Controls, Win32 Controls or using any other technologies)

I am happy to answer if you have more questions!!!
Thanks, Venkat






Venkatakarthikeyan Natarajamoorhty

GeneralRe: Questions
Kent Boogaart
16:15 26 Mar '07  
Thanks for the reply, but I think you've misunderstood some things about the WPF/CAB layer project.

Firstly, the project started out as a single DLL that could be used with the existing CAB DLLs to add support for WPF without resorting to Winforms interop. A lot of people - including me - are coding WPF applications and do not want to have to use Winforms interop in order to use CAB (whether it is explicit or done automatically by the workspaces doesn't matter - it's still interop).

I eventually included the complete CAB source a couple of technical reasons:
1. The original CAB source does not give assemblies a strong name. I needed the assemblies to be strongly-named.
2. The original CAB source does not provide a generic mechanism to cancel smart part activations. I needed this to support validation scenarios in my WPF application.

I have NOT re-implemented CAB - I have merely tweaked it as required.

Secondly, nothing precludes you from displaying a Winforms smart part using my CAB layer. You can either:
1. Wrap your smart part in a WPF smart part and use crossbow to do interop.
2. Modify the existing workspaces to do this automatically for you.

Indeed, the sample application you can download with my code include an example of showing a Winforms control (the web browser). I created the WPF/CAB layer to support our WPF application. I do not need interop with Winforms smart parts so I did not add that support to the workspaces.

> using the IWorkspace/Workspace interface generics parameters, you can write any workspaces that hosts any technology parts

Yes, this is exactly what my project does - provides workspace implementations for WPF technology parts. I guess I'm just not seeing what the advantage of your approach is given most people's requirements, and I'm failing to see how it would scale to a real-world project (or even a sample project such as the bank teller one).
GeneralRe: Questions
Venkatakarthikeyan Natarajamoorthy
5:15 28 Mar '07  
If your WPF layer resolves many issues, that would be awesome! This article and sample workspace implementation is not a complete solution for any smart client projects. It gives a way to develop any workspaces that bound to any technologies as CAB built so far. If you add some more workspaces, the bank teller sample application would be ready, as you like.

You didn't talk anything about issues/defects I found in your Window Workspace. So I hope that - you understood - those are really critical defects and if somebody uses your layer they should not affect with your code. Please resolve them if you like. FYI - "Interop" is not a extra burden. Its not like if you don’t like you should not use it. This sample just gets window's handle using Interop. All the workspaces must have a parent window as a shell window or any other windows in the shell. (Ref: Basic windows programming)

Answers for your two points:

1. CAB is not a business product from Microsoft. It is just practices come with source code (Not as a binaries). If your business needs, you can strong name your CAB assemblies.
2. Smart Parts are created on the fly using OB (object builder) foundations along with builder strategies. (I am planning to write another article - how to write CAB builder strategies) If you want to remove smart part, you can simply remove from the Smart Parts collection. There are millions of ways to extend CAB behaviors based on the project needs.

Do you know - If you run Microsoft FxCop (Analysis Tool) against CAB, it throws thousands of breaking violations. Will you conclude CAB is not a standard one?

Venkat Nataraj

GeneralRe: Questions
DarrelMiller
17:48 18 Apr '07  
Hey guys, you need to both take a deep breath and relax. You are both solving two different but very valid problems.

Some people have built Windows Forms apps based on CAB and would like to start introducing some WPF elements into their existing app. That is where Venkat's approach makes the most sense.

Other people may be starting a new application, like the idea of CAB but don't want to start using WinForms now when WPF is already here. From what I have seen of WPF so far, it is a major step forward and I wouldn't want CAB to be limited to Winforms forever. In fact if you look at WCF and WF there are elements of each that could easily replace large chunks of CAB code.

You guys are working in similar area but are in no way competing against each other, you should be collaborating instead of picking at each other.

Peace!

Darrel
GeneralRe: Questions
Kent Boogaart
2:40 2 May '07  
Thanks Darrel. I did not mean to sound like I was picking on this at all, and I'm sorry if I came across that way. All I was doing was trying to understand the points that Venkat was making (I confess I still don't understand). Your reply makes complete sense to me (and was my initial assumption when I first saw the screenshot for the article), but it is not the point Venkat was making.

Again, no offence intended at all. Big Grin
GeneralRe: Questions
Venkatakarthikeyan Natarajamoorthy
12:44 6 Jul '07  
Please visit this site: http://windowsclient.net/Acropolis/[^]

Complete bug-free patterns/solution from Microsoft for XAML ONLY Smart Client applications



Venkat Nataraj

GeneralRe: Questions
Kent Boogaart
15:54 6 Jul '07  
Yes, or if you need something that works today, please visit http://www.codeplex.com/scsfcontrib/[^].
GeneralInnovative Architectural Idea!!!
sivas_v
16:04 22 Mar '07  
Without wrappers, creating XAML workspaces and adding into CAB is really good one. Kudos to author
GeneralRe: Innovative Architectural Idea!!!
Venkatakarthikeyan Natarajamoorthy
12:44 26 Mar '07  
Thank you for your feedback

Venkatakarthikeyan Natarajamoorhty


Last Updated 22 Mar 2007 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010