Outlookbar and Presentation Model with DataTemplates

Oct 26, 2008 at 1:05 AM
I'm implementing a outlook style application as described by Ezequiel Jadib here: http://blogs.southworks.net/ejadib/2008/07/22/use-the-outlookbar-in-your-compositewpf-prism-applications/.  This is working fine with the typical view that derives from a usercontrol.

Also, I want to use the presentation model with data templates that Julian Dominguez here: http://blogs.southworks.net/jdominguez/2008/09/presentation-model-with-datatemplates-in-compositewpf-prism-sample/.  This also is working fine for the shell presentation.

The interesting thing is the view for each outlook navigation bar.  The method used to pass a view into the outlook bar OutlookBarControl.SetOutlookBarMetadata requires a view that is a dependency object.  So I made my presentation model derive from a dependency object.  This worked fine and the view displays properly as and where expected.  Great!

However, the title of the bar and the view which is normally set from the given OutlookBarMetadata Title property is being ignored and is blank in both places.

I have not yet dug into the source code.  Thought I'd ask about this first!  Also want to thank all the P&P guys for great work.  Very good to know the practices are including agile thinking.  I'm excited about the compositeWPF and the contrib project.

I appreciate all the continued posts and blogs as well.  And of course especially Julian and Ezequiel since I'm using your code.  Ezequiel, any further progress on the outlook bar?

Sean
Oct 29, 2008 at 1:44 AM
Ok, I took another (closer) look and found my own mistake.  I had left the UserControl Derived view type instantiation in the code during my transition and continued to pass it instead of the new model type when I set the OutlookbarMetaData.   :)
Oct 29, 2008 at 1:58 AM
Ok, I'm glad you found the solution, and sorry for not getting to you sooner :)

I will be interested in hearing how your project evolves with the DataTemplates approach. I still didn't have the time to create some more blog posts around it, because we're currently working with Silverlight a lot, where automatically injected DataTemplates are not supported (neither the powerful relative binding capabilities that WPF has).

Regarding agile, the Prism team is very into it, and we hope that reflects on how we implement the things that are actually useful to the community through their feedback. There is a blog post from Glenn Block (our former product manager) that talks a little on how we develop and contains a few videos if you are interested: The Prism team and how we develop

Thanks for the feedback
Julian Dominguez
Oct 29, 2008 at 3:21 AM
Edited Oct 29, 2008 at 3:36 AM
Thanks for the link.  I watched the video, its good to see an agile team in action!

BTW, I also just posted an issue.  It would be great if you could take care of it right away.  Just kidding.  Anyway, its an easy fix, I've already done it on my box.  Here's the issue FYI: http://www.codeplex.com/CompositeWPF/WorkItem/View.aspx?WorkItemId=3339

Oh, and I'll be sure to keep you updated on my project's evolution as anything interesting comes up.  My goal is to implement a basic outlook style smartclient 'framework/shell' based on the CAL using best practices guided by the recommendations here and at the CompositeWPF codeplex site for all the basic functionality, ie. commands, menus, events as appropriate.  This, so that anything I can currently do in Winforms from a LOB perspective, I can also quickly do in WPF.

I'm no WPF expert, but its great stuff, especially, I feel, in combination with the best practices and patterns made all the more available thanks to you and your team's work.

Regards,
Sean
Nov 9, 2008 at 1:38 AM
Edited Nov 9, 2008 at 1:42 AM
Julian,

I'm bumping up against the limitation you mention in your article (http://blogs.southworks.net/jdominguez/2008/09/presentation-model-with-datatemplates-in-compositewpf-prism-sample/) where you say:

One drawback of this particular implementation is that if I have a more complex Control that not only binds, but interacts with a region, there is no out-of-the-box behavior that will use Region Adapters to enhance this binding (in the example the ItemsControl just binds to the Views collection exposed by the region and that’s it).

But don’t discard this approach prematurely; if you need such a behavior, it could be easily solved by creating an attached behavior other than RegionManager.RegionName (BTW, this attached property IS an attached behavior…) that takes an existing region in the model and hooks it up with the target Control appropriately.

My question regards your suggestion to add another attached property, that takes a Region and hooks it up.  I've done just that adding an attached property named IsAttached to the RegionManager class.  And as you seem to suggest, I have also added the static method public static void SetIsAttached(IRegion region, bool IsAttached) to do the work.  My approach has been to somehow get the DependencyObject instance the region correlates with inside this method and then attach the behavior in the set call back.

You seem to imply there should be a way.  But I've been working on this for a couple of hours now.  Am I missing something.  Is there some magic way to get the a regions correlated dependency object?  Got any ideas?  Or did you have something else in mind here I'm not understanding?

Thanks
Sean

PS. For reference here's all the code I've added as POC to the RegionManager:

public
static readonly DependencyProperty IsAttachedProperty = DependencyProperty.RegisterAttached("IsAttached", typeof(Boolean), typeof(RegionManager), new PropertyMetadata(OnSetIsAttachedCallback));

public
static void SetIsAttached(IRegion region, bool IsAttached){
// attempts to get the target follow here
DependencyObject target = null;
DependencyObject child = null;
foreach (DependencyObject item in region.Views){
child = item;
break;}
SetIsAttached(target, IsAttached);
}

public static void SetIsAttached(DependencyObject target, bool isAttached){
target.SetValue(IsAttachedProperty, isAttached);}

public
static bool GetIsAttached(DependencyObject target){
return (bool)target.GetValue(IsAttachedProperty);}

private
static void OnSetIsAttachedCallback(DependencyObject region, DependencyPropertyChangedEventArgs args)
{
if (GetIsAttached(region)){
RegionNameBehavior behavior = new RegionNameBehavior(region);
behavior.Attach();}
}

Nov 10, 2008 at 6:25 PM
Hi Sean,

The approach I was trying to imply is that you could have an attached property like the following:

public static readonly DependencyProperty AttachRegionProperty = DependencyProperty.RegisterAttached("AttachRegion", typeof(IRegion), typeof(RegionManager), new PropertyMetadata(OnAttachRegionCallback));


So instead of setting a boolean, you set the IRegion value in that property, and the callback has some code (a.k.a. "behavior") that uses a region adapter to adapt the control to the existing instance of the region in your ViewModel:

private static void OnSetAttachRegionCallback(DependencyObject regionTarget, DependencyPropertyChangedEventArgs args)
{
    // get the region adapter mapping for the regionTarget. The region adapter should be updated to accept an overload that takes an existing region
    // call Initialize on the region adapter passing it the regionTarget, and the instance of the region to attach to (args.NewValue).
}


I hope this makes it more clear. I'm definetely thinking of creating a more detailed blog post about this in the following days (probably this weekend).

Julian Dominguez
http://blogs.southworks.net/jdominguez
Nov 10, 2008 at 7:49 PM
Thank you.  I'm still wrapping my mind around the WPF way of doing things (and the CAL).  So I will be looking forward to the post you mention.

In the meanwhile I may play this week with this as I'm in a slow time finishing 2 weeks till I start a new position, maybe posting another question or two as I continue forward.

Thanks again.