xamDockManager RegionAdapter - Any hint or tip ?

Jul 11, 2008 at 8:23 PM
I am trying to integrate Infragistics xamDockManager and Composite WPF.

I need to create  a RegionAdapter for the TabGroupPane:

                     <igDock:XamDockManager Grid.Row="1" x:Name="dockManager">
            <igDock:DocumentContentHost  >
                <igDock:SplitPane >

                    <igDock:TabGroupPane cal:RegionManager.RegionName="{x:Static infrastructure:RegionNames.Editor}" >

                    </igDock:TabGroupPane>

                </igDock:SplitPane>
            </igDock:DocumentContentHost>

I've followed the instructions provided in the documentation copying the code form the SelectorRegionAdapter
(TabGroupPane : TabControl and if I use the standard TabControl the SelectorRegionAdapter works fine).

In the case of  TabGroupPane it gives the following error : TabGroupPane can only contain 'ContentPane' and 'ContentPanePlaceholder' instances.

If I were in the Shell code behind, I would do the following (but obviosuly that's not the idea with Composite WPF):

             ContentPane newContentPane = new ContentPane();
            newContentPane.Content = textEditorPresenter.View;
            newContentPane.Activate();
            this.dockManager.AddDocument(textEditorPresenter.Title, newContentPane);

So, it's not very clear to me where should I add such code to the RegionAdapter.

Any hint or tip is welcomed.

Thanks,
Claudio.


Jul 11, 2008 at 8:44 PM
Looks like I'm not the only one, but you beat me to it....
:-)
This is EXACTLY my problem and it looks like we went about the solution in a similar way. I hope it's not too much trouble to wire up. I've posted to the Infragistics forum, too. I'll be sure to respond to this thread if I get it working.
Jul 15, 2008 at 1:26 AM

I haven't completely worked this out, but I've been able to bind a collection of views to the TabGroupPane by implementing a custom region adapter and region for the TabGroupPane ItemsControl. I got the message below until I modified the add methods in the custom region to wrap the content in a ContentPane if the input wasn't already one. I also didn't get selection changed functionality working at first because I was setting the tab group pane's ItemsSource property to the regions views collection. Apparently this isn't supported by this extension to the ItemsControl.

I don't like that the TabGroupPane is an ItemsControl, but doesn't support ItemsSource. I had to jump through some hoops to handle when the collection changes instead of just letting it do its thing. This might still come back to bite me. I'm not sure why Infragistics likes to do this sort of thing, but it makes it more difficult to use their controls (ie: InitializeRow instead of ItemDataBound).

I'm not sure if what I've done will work in every case, or even if it works completely for my needs, but I've been able to move forward. If you'd like I could send you what I've got. If it doesn't meet your needs you can modify and share back.



cpi wrote:
I am trying to integrate Infragistics xamDockManager and Composite WPF.

I need to create  a RegionAdapter for the TabGroupPane:

                     <igDock:XamDockManager Grid.Row="1" x:Name="dockManager">
            <igDock:DocumentContentHost  >
                <igDock:SplitPane >

                    <igDock:TabGroupPane cal:RegionManager.RegionName="{x:Static infrastructure:RegionNames.Editor}" >

                    </igDock:TabGroupPane>

                </igDock:SplitPane>
            </igDock:DocumentContentHost>

I've followed the instructions provided in the documentation copying the code form the SelectorRegionAdapter
(TabGroupPane : TabControl and if I use the standard TabControl the SelectorRegionAdapter works fine).

In the case of  TabGroupPane it gives the following error : TabGroupPane can only contain 'ContentPane' and 'ContentPanePlaceholder' instances.

If I were in the Shell code behind, I would do the following (but obviosuly that's not the idea with Composite WPF):

             ContentPane newContentPane = new ContentPane();
            newContentPane.Content = textEditorPresenter.View;
            newContentPane.Activate();
            this.dockManager.AddDocument(textEditorPresenter.Title, newContentPane);

So, it's not very clear to me where should I add such code to the RegionAdapter.

Any hint or tip is welcomed.

Thanks,
Claudio.





Jul 15, 2008 at 2:14 AM
Yes, please send it. I was doing it the same way you described until I got to the ItemsSource issue (see http://forums.infragistics.com/forums/t/10521.aspx).
I think once we have something stable we can post it somewhere in this site or send it to Infragistics as a start of something similar to the CAB Kit.

Claudio.
Jul 24, 2008 at 9:05 PM
As I didn't receive any code, I continued developing my own adapter which I have almost finished.
Once finished I will contribute to http://www.codeplex.com/CompositeWPFContrib

Jul 25, 2008 at 12:41 AM
Edited Jul 25, 2008 at 12:45 AM
Sorry, got caught up doing a guidance package for composite wpf. I also ran into a few snags around activating views in the tabpanegroup and haven't had the opportunity to debug. I'd be interested to compare your solution with mine. I've never uploaded anything to codeplex before. I'm not satisfied with the quality of my solution, but I'll upload it and hopefully someone more familiar with Infragistics and Composite WPF can fix errors in implementation.

I've requested to be a contributor. In the mean time, maybe you can contact me via email and I'll send you what I've got?
Jul 25, 2008 at 4:18 PM
I am facing some issues when having more than 1 TabGroupPane. When having 1 TabGroupPane everything works as expected.

Regarding email, I already contact you on July 14 (via codeplex contact) and I haven't received any feedback.
Also, I 've requested to be a contributor to the CompositeWPFContrib project.

Thanks,
Claudio.


Jul 25, 2008 at 6:10 PM

OK, I don't want to hold you up, so I'll brave criticism and post the code inline. Take a look and tell me what you think needs work. My implementation requires that the views be added with a name. It may be too tightly coupled to my needs, but it'll be good to try to plug into it and see if it meets your needs.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls.Primitives;
using Microsoft.Practices.Composite.Regions;
using System.Windows.Controls;
using System.Collections.Specialized;
using Infragistics.Windows.DockManager;
using Microsoft.Practices.Composite.Wpf.Regions;
using System.Windows.Data;

namespace Composite.Wpf.Extensions
{
 /// <summary>
 /// Adapter that creates a new <see cref="Region"/> and binds all
 /// the views to the adapted <see cref="Selector"/>.
 /// It also keeps the <see cref="IRegion.ActiveViews"/> and the selected items
 /// of the <see cref="Selector"/> in sync.
 /// </summary>
 public class TabGroupPaneRegionAdapter : SelectorRegionAdapter
 {
  /// <summary>
  /// Adapts an <see cref="Selector"/> to an <see cref="IRegion"/>.
  /// </summary>
  /// <param name="region">The new region being used.</param>
  /// <param name="regionTarget">The object to adapt.</param>
  protected override void Adapt(IRegion region, Selector regionTarget)
  {
   TabGroupPane typedRegionTarget = regionTarget as TabGroupPane;
   if (typedRegionTarget == null)
    throw new NotSupportedException(String.Format("Attempt to adapt {0} using {1} adapter failed. Type not supported.", regionTarget.GetType().Name, this.GetType().Name));

   TabGroupPaneRegion typedRegion = region as TabGroupPaneRegion;
   if (typedRegion == null)
    throw new NotSupportedException(String.Format("Attempt to adapt {0} region using {1} adapter failed. Region type not supported.", region.GetType().Name, this.GetType().Name));

   if (regionTarget.ItemsSource != null || (BindingOperations.GetBinding(regionTarget, ItemsControl.ItemsSourceProperty) != null))
    throw new InvalidOperationException(Resources.ItemsControlHasItemsSourceException);

   if (typedRegionTarget.Items.Count > 0)
   {
    //Control must be empty before setting ItemsSource
    //Not tracking items in the target might be bad. Encountering in attempting to save layout.
    //foreach (object childItem in typedRegionTarget.Items)
    //{
    //    typedRegion.Add(childItem);
    //}
    typedRegionTarget.Items.Clear();
   }

   //typedRegion.Views.CollectionChanged += new NotifyCollectionChangedEventHandler(Views_CollectionChanged);
   //this.setViews(typedRegion);

   //regionTarget.ItemsSource = region.Views;
  }

  /// <summary>
  /// Attach new behaviors.
  /// </summary>
  /// <param name="region">The region being used.</param>
  /// <param name="regionTarget">The object to adapt.</param>
  /// <remarks>
  /// This class attaches the base behaviors and also listens for changes in the
  /// activity of the region or the control selection and keeps the in sync.
  /// </remarks>
  protected override void AttachBehaviors(IRegion region, Selector regionTarget)
  {
   //base.AttachBehaviors(region, regionTarget);

   TabGroupPane typedTarget = regionTarget as TabGroupPane;
   TabGroupPaneRegion typedRegion = region as TabGroupPaneRegion;

   //The behavior uses weak references while listening to events to prevent memory leaks
   //when destroying the region but not the control or viceversa.
   SelectorRegionSyncBehavior syncBehavior = new SelectorRegionSyncBehavior(regionTarget, region);
   syncBehavior.Attach();
   //The behavior uses weak references while listening to events to prevent memory leaks
   //when destroying the region but not the control or viceversa.
   TabGroupPanesSyncBehavior tabSyncBehavior = new TabGroupPanesSyncBehavior(typedRegion, typedTarget, region.Views);
   tabSyncBehavior.Attach();
  }

  //private void setViews(TabGroupPaneRegion region)
  //{
  //    Selector target = base.GetSelector();
  //    TabGroupPane typedTarget = target as TabGroupPane;

  //    if (typedTarget != null)
  //    {
  //        typedTarget.Items.Clear();
  //        foreach (object tab in region.Views)
  //        {
  //            typedTarget.Items.Add(tab);
  //        }
  //        // typedTarget.ItemsSource = region.Views;
  //    }
  //}

  //private void Views_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
  //{
  //    IRegion region = base.GetRegion();
  //    TabGroupPaneRegion typedRegion = region as TabGroupPaneRegion;

  //    if (typedRegion != null)
  //        this.setViews(typedRegion);
  //}

  /// <summary>
  /// Creates a new instance of <see cref="Region"/>.
  /// </summary>
  /// <returns>A new instance of <see cref="Region"/>.</returns>
  protected override IRegion CreateRegion()
  {
   return new TabGroupPaneRegion();
  }

  private class TabGroupPanesSyncBehavior
  {
   private readonly WeakReference _collectionWeakReference;
   private readonly WeakReference _regionWeakReference;
   private readonly WeakReference _selectorWeakReference;

   /// <summary>
   /// Initializes a new instance of <see cref="CollectionActiveAwareBehavior"/>.
   /// </summary>
   /// <param name="collection">The collection to monitor.</param>
   /// <remarks>This instance will keep a <see cref="WeakReference"/> to the
   /// <paramref name="collection"/>, so the collection can be garbage collected.</remarks>
   /// <param name="region">The region to monitor.</param>
   /// <param name="target">The target to monitor.</param>
   public TabGroupPanesSyncBehavior(TabGroupPaneRegion region, TabGroupPane target, INotifyCollectionChanged collection)
   {
    _collectionWeakReference = new WeakReference(collection);
    _regionWeakReference = new WeakReference(region);
    _selectorWeakReference = new WeakReference(target);
   }

   /// <summary>
   /// Attaches the behavior to the <see cref="INotifyCollectionChanged"/>.
   /// </summary>
   public void Attach()
   {
    INotifyCollectionChanged collection = GetCollection();
    if (collection != null)
     collection.CollectionChanged += OnCollectionChanged;

    Selector selector = GetSelector();
    IRegion region = GetRegion();
    if (selector != null && region != null)
    {
     selector.SelectionChanged += OnSelectionChanged;
     region.ActiveViews.CollectionChanged += OnActiveViewsChanged;
    }
   }

   /// <summary>
   /// Detaches the behavior from the <see cref="INotifyCollectionChanged"/>.
   /// </summary>
   public void Detach()
   {
    INotifyCollectionChanged collection = GetCollection();
    if (collection != null)
     collection.CollectionChanged -= OnCollectionChanged;

    Selector selector = GetSelector();
    if (selector != null)
    {
     selector.SelectionChanged -= OnSelectionChanged;
    }
    IRegion region = GetRegion();
    if (region != null)
    {
     region.ActiveViews.CollectionChanged -= OnActiveViewsChanged;
    }
   }

   private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
   {
    TabGroupPaneRegion region = GetRegion();
    TabGroupPane selector = GetSelector();
    if (region == null || selector == null)
    {
     Detach();
    }
    else
    {
     if (selector == e.OriginalSource)
     {
      foreach (object item in e.RemovedItems)
      {
       if (region.ActiveViews.Contains(item))
       {
        region.Deactivate(item);
       }
      }
      foreach (object item in e.AddedItems)
      {
       if (region.Views.Contains(item))
        region.Activate(item);
      }
     }
    }
   }

   private void OnActiveViewsChanged(object sender, NotifyCollectionChangedEventArgs e)
   {
    TabGroupPane selector = GetSelector();
    TabGroupPaneRegion region = GetRegion();
    if (region == null || selector == null)
    {
     Detach();
    }
    else
    {
     if (e.Action == NotifyCollectionChangedAction.Add)
     {
      if (selector.Items.Contains(e.NewItems[0]))
       selector.SelectedItem = e.NewItems[0];
     }
     else if (e.Action == NotifyCollectionChangedAction.Remove &&
        e.OldItems.Contains(selector.SelectedItem))
     {
      selector.SelectedItem = null;
     }
    }
   }

   private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
   {
    //if (e.Action == NotifyCollectionChangedAction.Add)
    //{
    //    foreach (object item in e.NewItems)
    //    {
    //        IActiveAware activeAware = item as IActiveAware;
    //        if (activeAware != null)
    //            activeAware.IsActive = true;
    //    }
    //}
    //else if (e.Action == NotifyCollectionChangedAction.Remove)
    //{
    //    foreach (object item in e.OldItems)
    //    {
    //        IActiveAware activeAware = item as IActiveAware;
    //        if (activeAware != null)
    //            activeAware.IsActive = false;
    //    }
    //}

    TabGroupPaneRegion region = GetRegion();
    TabGroupPaneRegion typedRegion = region as TabGroupPaneRegion;

    Selector target = GetSelector();
    TabGroupPane typedTarget = target as TabGroupPane;

    if (typedTarget != null && typedRegion != null)
    {
     typedTarget.Items.Clear();
     foreach (object tab in region.Views)
     {
      typedTarget.Items.Add(tab);
     }
     // typedTarget.ItemsSource = region.Views;
    }
   }

   private INotifyCollectionChanged GetCollection()
   {
    return _collectionWeakReference.Target as INotifyCollectionChanged;
   }

   private TabGroupPane GetSelector()
   {
    return _selectorWeakReference.Target as TabGroupPane;
   }

   private TabGroupPaneRegion GetRegion()
   {
    return _regionWeakReference.Target as TabGroupPaneRegion;
   }

  }

  private class SelectorRegionSyncBehavior
  {
   private readonly WeakReference _selectorWeakReference;
   private readonly WeakReference _regionWeakReference;

   internal SelectorRegionSyncBehavior(Selector selector, IRegion region)
   {
    _selectorWeakReference = new WeakReference(selector);
    _regionWeakReference = new WeakReference(region);
   }

   internal void Attach()
   {
    Selector selector = GetSelector();
    IRegion region = GetRegion();
    if (selector != null && region != null)
    {
     selector.SelectionChanged += OnSelectionChanged;
     region.ActiveViews.CollectionChanged += OnActiveViewsChanged;
    }
   }

   internal void Detach()
   {
    Selector selector = GetSelector();
    if (selector != null)
    {
     selector.SelectionChanged -= OnSelectionChanged;
    }
    IRegion region = GetRegion();
    if (region != null)
    {
     region.ActiveViews.CollectionChanged -= OnActiveViewsChanged;
    }
   }

   private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
   {
    IRegion region = GetRegion();
    Selector selector = GetSelector();
    if (region == null || selector == null || selector.ItemsSource != region.Views)
    {
     Detach();
    }
    else
    {
     if (selector == e.OriginalSource)
     {
      foreach (object item in e.RemovedItems)
      {
       if (region.ActiveViews.Contains(item))
       {
        region.Deactivate(item);
       }
      }
      foreach (object item in e.AddedItems)
      {
       region.Activate(item);
      }
     }
    }
   }

   private void OnActiveViewsChanged(object sender, NotifyCollectionChangedEventArgs e)
   {
    Selector selector = GetSelector();
    IRegion region = GetRegion();
    if (region == null || selector == null || selector.ItemsSource != region.Views)
    {
     Detach();
    }
    else
    {
     if (e.Action == NotifyCollectionChangedAction.Add)
     {
      selector.SelectedItem = e.NewItems[0];
     }
     else if (e.Action == NotifyCollectionChangedAction.Remove &&
        e.OldItems.Contains(selector.SelectedItem))
     {
      selector.SelectedItem = null;
     }
    }
   }

   private Selector GetSelector()
   {
    return _selectorWeakReference.Target as Selector;
   }

   private IRegion GetRegion()
   {
    return _regionWeakReference.Target as IRegion;
   }
  }
 }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Composite.Regions;
using Microsoft.Practices.Composite.Wpf.Regions;
using Infragistics.Windows.DockManager;
using System.Globalization;
using System.Collections.ObjectModel;
using System.Windows;
using Microsoft.Practices.Composite.Wpf;

namespace Composite.Wpf.Extensions
{

 /// <summary>
 /// Implementation of <see cref="IRegion"/> that allows multiple active views.
 /// </summary>
 public class TabGroupPaneRegion : IRegion
 {
  private ObservableCollection<ItemMetadata> _itemMetadataCollection;
  private IViewsCollection _views;
  private IViewsCollection _activeViews;

  /// <summary>
  /// Gets a readonly view of the collection of views in the region.
  /// </summary>
  /// <value>An <see cref="IViewsCollection"/> of all the added views.</value>
  public virtual IViewsCollection Views
  {
   get
   {
    if (_views == null)
    {
     _views = new ViewsCollection(ItemMetadataCollection, x => true);
    }
    return _views;
   }
  }

  /// <summary>
  /// Gets a readonly view of the collection of all the active views in the region.
  /// </summary>
  /// <value>An <see cref="IViewsCollection"/> of all the active views.</value>
  public virtual IViewsCollection ActiveViews
  {
   get
   {
    if (_activeViews == null)
    {
     _activeViews = new ViewsCollection(ItemMetadataCollection, x => x.IsActive);
    }
    return _activeViews;
   }
  }

  ///<overloads>Adds a new view to the region.</overloads>
  /// <summary>
  /// Adds a new view to the region.
  /// </summary>
  /// <param name="view">The view to add.</param>
  /// <returns>The <see cref="IRegionManager"/> that is set on the view if it is a <see cref="DependencyObject"/>. It will be the current region manager when using this overload.</returns>
  public IRegionManager Add(object view)
  {
   ContentPane add = wrapInContentPane(view, String.Empty);
   return Add(add, null, false);

  }

  /// <summary>
  /// Adds a new view to the region.
  /// </summary>
  /// <param name="view">The view to add.</param>
  /// <param name="viewName">The name of the view. This can be used to retrieve it later by calling <see cref="IRegion.GetView"/>.</param>
  /// <returns>The <see cref="IRegionManager"/> that is set on the view if it is a <see cref="DependencyObject"/>. It will be the current region manager when using this overload.</returns>
  public IRegionManager Add(object view, string viewName)
  {
   if (string.IsNullOrEmpty(viewName))
    throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Composite.Wpf.Extensions.Resources.StringCannotBeNullOrEmpty, "viewName"));

   ContentPane add = wrapInContentPane(view, viewName);
   return Add(add, viewName, false);
  }

  /// <summary>
  /// Adds a new view to the region.
  /// </summary>
  /// <param name="view">The view to add.</param>
  /// <param name="viewName">The name of the view. This can be used to retrieve it later by calling <see cref="IRegion.GetView"/>.</param>
  /// <param name="createRegionManagerScope">When <see langword="true"/>, the added view will receive a new instance of <see cref="IRegionManager"/>, otherwise it will use the current region manager for this region.</param>
  /// <returns>The <see cref="IRegionManager"/> that is set on the view if it is a <see cref="DependencyObject"/>.</returns>
  public virtual IRegionManager Add(object view, string viewName, bool createRegionManagerScope)
  {
   IRegionManager regionManager = createRegionManagerScope ? this.RegionManager.CreateRegionManager() : this.RegionManager;
   ContentPane add = wrapInContentPane(view, viewName);
   InnerAdd(add, viewName, regionManager);
   return regionManager;
  }

  private static ContentPane wrapInContentPane(object view, string viewName)
  {
   ContentPane add = view as ContentPane;

   ContentPanePlaceholder ph = view as ContentPanePlaceholder;

   if (add == null && ph == null && view != null)
   {
    add = new ContentPane();
    add.SetValue(ContentPane.NameProperty, ViewUtility.GetViewSafeName(viewName));
    add.Content = view;
   }
   if (add != null && !String.IsNullOrEmpty(viewName))
    add.Header = viewName;

   return add;
  }

  /// <summary>
  /// Removes the specified view from the region.
  /// </summary>
  /// <param name="view">The view to remove.</param>
  public virtual void Remove(object view)
  {
   ItemMetadata itemMetadata = GetItemMetadataOrThrow(view);

   ItemMetadataCollection.Remove(itemMetadata);

   DependencyObject dependencyObject = view as DependencyObject;
   if (dependencyObject != null && Microsoft.Practices.Composite.Wpf.Regions.RegionManager.GetRegionManager(dependencyObject) == this.RegionManager)
   {
    dependencyObject.ClearValue(Microsoft.Practices.Composite.Wpf.Regions.RegionManager.RegionManagerProperty);
   }
  }

  /// <summary>
  /// Marks the specified view as active.
  /// </summary>
  /// <param name="view">The view to activate.</param>
  public virtual void Activate(object view)
  {
   ContentPane add = wrapInContentPane(view, String.Empty);
   ItemMetadata itemMetadata = GetItemMetadataOrThrow(add);

   if (!itemMetadata.IsActive)
   {
    itemMetadata.IsActive = true;
   }
  }

  /// <summary>
  /// Marks the specified view as inactive.
  /// </summary>
  /// <param name="view">The view to deactivate.</param>
  public virtual void Deactivate(object view)
  {
   ContentPane add = wrapInContentPane(view, String.Empty);
   ItemMetadata itemMetadata = GetItemMetadataOrThrow(add);

   if (itemMetadata.IsActive)
   {
    itemMetadata.IsActive = false;
   }
  }

  /// <summary>
  /// Returns the view instance that was added to the region using a specific name.
  /// </summary>
  /// <param name="viewName">The name used when adding the view to the region.</param>
  /// <returns>Returns the named view or <see langword="null"/> if the view with <paramref name="viewName"/> does not exist in the current region.</returns>
  public virtual object GetView(string viewName)
  {
   if (string.IsNullOrEmpty(viewName))
    throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Composite.Wpf.Extensions.Resources.StringCannotBeNullOrEmpty, "viewName"));

   ItemMetadata metadata = ItemMetadataCollection.FirstOrDefault(x => x.Name == ViewUtility.GetViewSafeName(viewName));

   if (metadata != null)
    return metadata.Item;

   return null;
  }

  /// <summary>
  /// Gets or sets the <see cref="IRegionManager"/> that will be passed to the views when adding them to the region, unless the view is added by specifying createRegionManagerScope as <see langword="true" />.
  /// </summary>
  /// <value>The <see cref="IRegionManager"/> where this <see cref="IRegion"/> is registered.</value>
  /// <remarks>This is usually used by implementations of <see cref="IRegionManager"/> and should not be
  /// used by the developer explicitely.</remarks>
  public IRegionManager RegionManager { get; set; }

  /// <summary>
  /// Gets the collection with all the views along with their metadata.
  /// </summary>
  /// <value>An <see cref="ObservableCollection{T}"/> of <see cref="ItemMetadata"/> with all the added views.</value>
  protected virtual ObservableCollection<ItemMetadata> ItemMetadataCollection
  {
   get
   {
    if (_itemMetadataCollection == null)
    {
     _itemMetadataCollection = new ObservableCollection<ItemMetadata>();
    }
    return _itemMetadataCollection;
   }
  }

  private void InnerAdd(object view, string name, IRegionManager regionManager)
  {
   string safeName = ViewUtility.GetViewSafeName(name);

   if (ItemMetadataCollection.FirstOrDefault(x => x.Item == view) != null)
    throw new InvalidOperationException(Composite.Wpf.Extensions.Resources.RegionViewExistsException);

   ItemMetadata itemMetadata = new ItemMetadata(view);
   if (!String.IsNullOrEmpty(safeName))
   {
    if (ItemMetadataCollection.FirstOrDefault(x => x.Name == safeName) != null)
     throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, Composite.Wpf.Extensions.Resources.RegionViewNameExistsException, safeName));
    itemMetadata.Name = safeName;
   }

   DependencyObject dependencyObject = view as DependencyObject;

   if (dependencyObject != null)
   {
    Microsoft.Practices.Composite.Wpf.Regions.RegionManager.SetRegionManager(dependencyObject, regionManager);
   }

   ItemMetadataCollection.Add(itemMetadata);
  }

  private ItemMetadata GetItemMetadataOrThrow(object view)
  {
   if (view == null)
    throw new ArgumentNullException("view");

   ItemMetadata itemMetadata = ItemMetadataCollection.FirstOrDefault(x => x.Item == view);
   if (itemMetadata == null)
    throw new ArgumentException(Composite.Wpf.Extensions.Resources.ViewNotInRegionException, "view");

   return itemMetadata;
  }
 }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Composite.Wpf.Extensions
{
 public class ViewUtility
 {
  public static string GetViewSafeName(string viewName)
  {
   return viewName.Replace(" ", String.Empty).Replace(":", String.Empty).Replace(",", String.Empty).Replace("\"", String.Empty).Replace("'", String.Empty).Replace(";", String.Empty).Replace("-", String.Empty).Replace("&", String.Empty).Replace("(", String.Empty).Replace(")", String.Empty).Replace(".", String.Empty);
  }
 }
}

Jul 28, 2008 at 12:32 AM
Hi,

I tried your solution for my case (IDE with multiple text editor tabs) and it doesn't work, it gives the exception below.
Also my case needs sync between the ActiveView and the Active ContentPane (really don't know if your solution manages this correctly, because of the the previous exception).
Also I don't like the fact of using ViewName as the header of the Tab.  I think the ViewName intention (CompositeWPF developers: correct me if I am wrong) is for an internal use only (not to be used as a description).

I think my extension is much simpler since it only consists of 1 class (public class TabGroupPaneRegionAdapter : RegionAdapterBase<TabGroupPane>)
Right now I am doing high level unit tests coverage and basic documentation, as requested by the CompositeWPFContrib project.
Once finished I will contribute my solution there.

Claudio.


System.InvalidOperationException
       Message="Specified element is already the logical child of another element. Disconnect it first."
       Source="PresentationFramework"
       StackTrace:
            at System.Windows.FrameworkElement.ChangeLogicalParent(DependencyObject newParent)
            at MS.Internal.FrameworkObject.ChangeLogicalParent(DependencyObject newParent)
            at System.Windows.FrameworkElement.AddLogicalChild(Object child)
            at System.Windows.Controls.ContentControl.OnContentChanged(Object oldContent, Object newContent)
            at System.Windows.Controls.ContentControl.OnContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
            at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
            at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
            at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, OperationType operationType)
            at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, OperationType operationType, Boolean isInternal)
            at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
            at System.Windows.Controls.ContentControl.set_Content(Object value)
            at Composite.Wpf.Extensions.TabGroupPaneRegion.wrapInContentPane(Object view, String viewName) in C:\Dev\Infragistics\IDE Prototype\CWPFNotepad\Composite.Wpf.Extensions\TabGroupPaneRegion.cs:line 108
            at Composite.Wpf.Extensions.TabGroupPaneRegion.Activate(Object view) in C:\Dev\Infragistics\IDE Prototype\CWPFNotepad\Composite.Wpf.Extensions\TabGroupPaneRegion.cs:line 139
            at CWPFNotepad.Modules.TextEditor.Controllers.TextEditorController.OpenTextEditor(FilePayload filePayload) in C:\Dev\Infragistics\IDE Prototype\CWPFNotepad\CWPFNotepad.Modules.TextEditor\Controllers\TextEditorController.cs:line 43
       InnerException:


Sep 2, 2008 at 9:19 PM
Hi Claudio,

Did you post your solution? I'm also looking into a solution for integrating xamDockManager with RegionManager and on googling saw that you have already raised it. Can I get the details of your solution?

Thanks,
Kunwar
Sep 2, 2008 at 9:24 PM
Kunwar,

You can download the adapter from http://www.codeplex.com/CompositeWPFContrib
You can see how to use it here: http://claudiopi.blogspot.com/2008/07/infragistics-tabgrouppane-region.html

Thanks,
Claudio.


On Tue, Sep 2, 2008 at 5:19 PM, kunwargadhok <notifications@codeplex.com> wrote:

From: kunwargadhok

Hi Claudio,

Did you post your solution? I'm also looking into a solution for integrating xamDockManager with RegionManager and on googling saw that you have already raised it. Can I get the details of your solution?

Thanks,
Kunwar

Read the full discussion online.

To add a post to this discussion, reply to this email (CompositeWPF@discussions.codeplex.com)

To start a new discussion for this project, email CompositeWPF@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com


Sep 3, 2008 at 2:43 PM
Thanks Claudio! I checked your blog and it is quite easy to understand. But I'm trying to download the latest sourcecode from http://www.codeplex.com/CompositeWPFContrib, but I get an errormessage that it is not a valid zipped file. Could you please upload the zipped file again or just tell me the contents that have changed and I can grab the files from source directory?

Thanks,
Kunwar
Sep 3, 2008 at 2:54 PM
Kunwar,

I just tried to download the zip file and I can open it without problems (By the way the .zip file is automatically built by the Source Control Server) .
The size of the .zip file is 1.041.540 bytes . Are you getting the same size ? With which tool are you trying to open it ?

Thanks,
Claudio.
Sep 3, 2008 at 2:59 PM
Actually I was getting that error yesterday evening but I did not post it last night, but this morning I'm getting a different error message -

----------
Content Does Not Match Content Type
The transferred file "http://www.codeplex.com/CompositeWPFContrib/SourceControl/DownloadSourceCode.aspx?changeSetId=14588/Trunk/Samples/PrismImageSearch/PrismImageSearch/Properties/AppManifest.xml" has been blocked by Webwasher, because the content of the file does not match the content type "text/xml" and Webwasher can not correct it.
-----------

Is there another way that I could get the .zip file? I have tried with both IE and Firefox.

Thanks.
Sep 3, 2008 at 3:12 PM
Interestingly I get the same error if I try to download any changesets under this link - http://www.codeplex.com/CompositeWPFContrib

But If I try to download the full source code under this - http://www.codeplex.com/CompositeWPF , IT WORKS (for e.g. this link works  http://www.codeplex.com/CompositeWPF/SourceControl/DownloadSourceCode.aspx?changeSetId=14905).

Kunwar