Running CompositeWPF without Application.Current

Topics: Prism v2 - WPF 3.5
May 15, 2009 at 4:43 PM
Edited May 16, 2009 at 12:14 AM

hi,

 I am able to setup CompositeWPF and run the shell, but there is no region manager associated with it!

I am initilising and running the Bootstrapper from within a Console app, but the value of

Dim RegionManager As RegionManager = Me.GetValue(RegionManager.RegionManagerProperty)

On the shell the DependancyProperty is "nothing" :(

I have the full source for TfsDynamicPolicy available on http://cid-57599e234f1ebc1c.skydrive.live.com/browse.aspx/.Public/Projects, but I have been at this for Ages... I had everything working when I was just using Unity, but I seam to be having an DependancyProperty problem...

I can confirm that it is running the SetRegionManager finction

Public Shared Sub SetRegionManager(ByVal target As DependencyObject, ByVal value As IRegionManager)
    target.SetValue(RegionManager.RegionManagerProperty, value)
End Sub

 

May 15, 2009 at 10:25 PM

Hi Martin,

 

Having taken a look at your code I found that the Shell you are resolving in the Edit() method of the TfsDynamicCheckInPolicy class is not the same as the one you create in the Bootstrapper (checking each HashCode). This is because the Shell is not registered in the container, but resolved instead.

 

To get the same instance I used the following code to register the shell in the unity container:

Bootstrapper.vb

Protected Overrides Function CreateShell() As System.Windows.DependencyObject

        Dim window As Shell = My.Unity.Resolve(Of Shell)()

        My.Unity.RegisterInstance(GetType(Shell), window)

        Return window1

End Function

TfsDynamicCheckInPolicy.vb

Public Function Edit(ByVal policyEditArgs As Microsoft.TeamFoundation.VersionControl.Client.IPolicyEditArgs) As Boolean Implements Microsoft.TeamFoundation.VersionControl.Client.IPolicyDefinition.Edit

        Dim window As Shell = My.Unity.Resolve(Of Shell)()

        If window.ShowDialog Then

            ' Use Values

            m_Data = My.Unity.Resolve(Of DynamicPolicyEngine)().Data

            Return True

        End If

        Return False

    End Function

 

Although this made the DependencyPropery return a correct RegionManager, this RegionManager had no Regions registered. The reason is that to create a new region the following validation is performed:

private static void OnSetRegionNameCallback(DependencyObject element, DependencyPropertyChangedEventArgs args)

        {

            if (!IsInDesignMode(element))

            {

                CreateRegion(element);

            }

        }

 

private static bool IsInDesignMode(DependencyObject element)

        {

            // Due to a known issue in Cider, GetIsInDesignMode attached property value is not enough to know if it's in design mode.

            return DesignerProperties.GetIsInDesignMode(element) || Application.Current == null

                   || Application.Current.GetType() == typeof(Application);

        }

 

The reason the region is never created is that the Application.Current is always null, because you are not creating an application. Have in mind that even if you modify that validation you could have other problems if you do not create an application.

 

Please let me know if this helps.

 

Damian Schenkelman

http://blogs.southworks.net/dschenkelman

May 15, 2009 at 11:30 PM
Edited May 15, 2009 at 11:31 PM

First, Thank you, thanks you! I spent hours looking at that and never thought... And I must aplogise for you having to look at my crappy VB code :), and that you had to make sense of my haistily typed and cryptic post...

Regarding the Applicaiton.Current being nothing:

Why is that? I am running it within a Console application? Does it have to be a WPF applicaiton object?

The final TfsDynamicPolicy class will be created by Visual Studio 2005/2008/2010 so the applicaiton in that case will be it.

 

Martin Hinshelwood

http://blog.hinshelwood.com

 

May 16, 2009 at 12:45 AM

There sems to be a couple of places that Application.Current is used. Can I sugest a way round this for those of use that are hosting WPF applications in an Application that is not a WPF application!

For the DelegateCommand, CompositeCommand, DefaultDispatcher (unused) objects instead of using Applicaiton.Current.Dispatch you use Dispatcher.Current which amounts to the same thing, but has no dependancy on the Application.

The IsInDesigneMode is a little more tricky, but can we asumb that in designe mode the UnityBootstrapper object is not involved? If so, can we not set a property on the RegionManager of IsDesigneMode or IsBootsrapper that negates this check?

Just my 2p worth...

I will try out these changes and update if they worked...

Martin Hinshelwood

http://blog.hinshelwood.com 

 

Jun 1, 2009 at 12:08 AM

Hi.

Martin, I've also encountred this issue. 

I'm using Prism with WPF which is hosted on a Outlook Add-In, Yeah I know :S.

And in this scenario as well Application.Current is absent.

I've changed to code to use Dispatcher.Current and it seems to be wokring quite well for event dispatching.

Haven't tried to rest.

Hope that helps.

Ariel

 

Jun 1, 2009 at 8:03 AM

I have implemented the changes and found no problems so far... :)