RadDocking with PRISM 4 + MVVM + MefBootstrapper

28 posts, 0 answers
  1. YYZRichard
    YYZRichard avatar
    20 posts
    Member since:
    Dec 2009

    Posted 29 Jan 2011 Link to this post

    I'm using the RegionAdapter from the following article.

    http://blogs.telerik.com/blogs/posts/09-08-31/using_the_raddocking_control_with_prism.aspx

    However, I'm using PRISM 4 + MVVM + MefBootstrapper.
    Has anybody successfully used the RegionAdapter with MefBootstrapper?

    I'm getting the following error message... 

    this

     

     

    .Container.Resolve

    Error 1 'System.ComponentModel.Composition.Hosting.CompositionContainer' does not contain a definition for 'Resolve' and the best extension method overload 'Microsoft.Practices.Unity.UnityContainerExtensions.Resolve<T>(Microsoft.Practices.Unity.IUnityContainer, params Microsoft.Practices.Unity.ResolverOverride[])'

    Thank you

    protected override RegionAdapterMappings ConfigureRegionAdapterMappings()
    {
        var mappings = base.ConfigureRegionAdapterMappings();
        mappings.RegisterMapping(typeof(RadPaneGroup), this.Container.Resolve<RadPaneGroupRegionAdapter>());
        return mappings;
    }
  2. YYZRichard
    YYZRichard avatar
    20 posts
    Member since:
    Dec 2009

    Posted 29 Jan 2011 Link to this post

    I figured out how to use RadDocking with PRISM 4 - MEF.

    Here's the bootstrapper.cs

    using YourCompany.YourApp.Infrastructure;
      
    using Microsoft.Practices.Prism.MefExtensions;
    using Microsoft.Practices.Prism.Modularity;
    using Microsoft.Practices.Prism.Regions;
    using Microsoft.Practices.Prism.UnityExtensions;
    using Microsoft.Practices.Unity;
      
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.Composition.Hosting;
    using System.Linq;
    using System.Text;
    using System.Windows;
      
    using Telerik.Windows.Controls;
      
    namespace YourCompany.YourApp.Desktop
    {
        [CLSCompliant(false)]
        public partial class Bootstrapper : MefBootstrapper
        {
            protected override DependencyObject CreateShell()
            {
                return this.Container.GetExportedValue<Shell>();
            }
      
            protected override void InitializeShell()
            {
                base.InitializeShell();
      
    #if SILVERLIGHT
                Application.Current.RootVisual = (Shell)this.Shell;            
    #else
                Application.Current.MainWindow = (Shell)this.Shell;
                Application.Current.MainWindow.Show();
    #endif
            }
      
            protected override void ConfigureAggregateCatalog()
            {
                base.ConfigureAggregateCatalog();
      
                this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(Bootstrapper).Assembly));
                this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(ModuleA).Assembly));
                this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(ModuleB).Assembly));
            }
      
            protected override void ConfigureContainer()
            {
                base.ConfigureContainer();
                //Container.RegisterType<MenuManager>(new ContainerControlledLifetimeManager()); 
            }
      
            protected override Microsoft.Practices.Prism.Regions.IRegionBehaviorFactory ConfigureDefaultRegionBehaviors()
            {
                var factory = base.ConfigureDefaultRegionBehaviors();
      
                factory.AddIfMissing("AutoPopulateExportedViewsBehavior", typeof(YourCompany.YourApp.Infrastructure.Behaviours.AutoPopulateExportedViewsBehaviour));
      
                return factory;
            }
      
            protected override RegionAdapterMappings ConfigureRegionAdapterMappings()
            {
                RegionAdapterMappings mappings = base.ConfigureRegionAdapterMappings();
      
                mappings.RegisterMapping(typeof(RadPaneGroup), this.Container.GetExportedValue<YourCompany.YourApp.Infrastructure.Adapters.RadPaneGroupRegionAdapter>());
      
                return mappings;
            }
        }
    }

    And here's the adapter for Telerik RadDocking:

    using System;
    using System.Collections.Specialized;
    using System.ComponentModel.Composition.Hosting;
    using System.ComponentModel.Composition;
    using System.Net;
    using System.Windows;
    using Telerik.Windows.Controls;
    using Telerik.Windows.Controls.Docking;
    using Microsoft.Practices.Prism.Regions;
    #if Silverlight
    using ItemsControl = Telerik.Windows.Controls.ItemsControl;
    #else
    using ItemsControl = System.Windows.Controls.ItemsControl;
    #endif
      
    namespace YourCompany.YourApp.Infrastructure.Adapters
    {
        [Export]
        public class RadPaneGroupRegionAdapter : RegionAdapterBase<RadPaneGroup>
        {
            [ImportingConstructor]
            public RadPaneGroupRegionAdapter(IRegionBehaviorFactory regionBehaviorFactory)
                : base(regionBehaviorFactory)
            {
            }
      
            protected override void Adapt(IRegion region, RadPaneGroup regionTarget)
            {
                region.Views.CollectionChanged += (s, e) =>
                {
                    switch (e.Action)
                    {
                        case NotifyCollectionChangedAction.Add:
                            foreach (var item in e.NewItems.OfType<RadPane>())
                            {
                                regionTarget.Items.Add(item);
                            }
                            break;
                        case NotifyCollectionChangedAction.Remove:
                            foreach (var item in e.OldItems.OfType<RadPane>())
                            {
                                item.RemoveFromParent();
                            }
                            break;
                        case NotifyCollectionChangedAction.Replace:
                            var oldItems = e.OldItems.OfType<RadPane>();
                            var newItems = e.NewItems.OfType<RadPane>();
                            var newItemsEnumerator = newItems.GetEnumerator();
                            foreach (var oldItem in oldItems)
                            {
                                var parent = oldItem.Parent as ItemsControl;
                                if (parent != null && parent.Items.Contains(oldItem))
                                {
                                    parent.Items[parent.Items.IndexOf(oldItem)] = newItemsEnumerator.Current;
                                    if (!newItemsEnumerator.MoveNext())
                                    {
                                        break;
                                    }
                                }
                                else
                                {
                                    oldItem.RemoveFromParent();
                                    regionTarget.Items.Add(newItemsEnumerator.Current);
                                }
                            }
                            break;
                        case NotifyCollectionChangedAction.Reset:
                            regionTarget
                                .EnumeratePanes()
                                .ToList()
                                .ForEach(p => p.RemoveFromParent());
      
                            foreach (var view in region.Views)
                            {
                                regionTarget.Items.Add(view);
                            }
      
                            break;
                        default:
                            break;
                    }
                };
      
                foreach (var view in region.Views.OfType<RadPane>())
                {
                    regionTarget.Items.Add(view);
                }
            }
      
            protected override IRegion CreateRegion()
            {
                return new AllActiveRegion();
            }
        }
    }
  3. UI for WPF is Visual Studio 2017 Ready
  4. Calabonga
    Calabonga avatar
    29 posts
    Member since:
    Nov 2009

    Posted 08 Feb 2011 Link to this post

    This is a good question! A have the same one!
    How RadPaneGroupRegionAdapter must work in MefBootstrapper mode?
    Why the IRegionAdapter can't see my region named by MainShellRegion 
    <t:RadDocking.DocumentHost>
                        <t:RadSplitContainer>
                            <t:RadPaneGroup
                                prism:RegionManager.RegionName="MainShellRegion" />
                        </t:RadSplitContainer>
                    </t:RadDocking.DocumentHost>

    ?!?!?
    Help as please!!!
  5. YYZRichard
    YYZRichard avatar
    20 posts
    Member since:
    Dec 2009

    Posted 08 Feb 2011 Link to this post

    Make sure you have the namespace declared at the top of the page, and watch out for case sensitivity (XAML is case-sensitive).

    <Window x:Class="MyCompany.MyApp.Desktop.Shell"
            xmlns:prism="http://www.codeplex.com/prism"
            xmlns:cal="http://www.codeplex.com/CompositeWPF"
            xmlns:URIUI="clr-namespace:MyCompany.MyApp.Infrastructure.UI;assembly=MyCompany.MyApp.Infrastructure"
            Title="Hello World" 
            Icon="Resources/HellowWorld.ico"
            mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="600"
            Height="718" Width="907">
      
        <Grid x:Name="LayoutRoot">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
      
            <telerik:RadDocking Grid.Row="1"
                                telerik:StyleManager.Theme="Windows7">
                  
                <telerik:RadDocking.DocumentHost>
                    <telerik:RadSplitContainer>
                        <telerik:RadPaneGroup x:Name="WorkRegion" prism:RegionManager.RegionName="WorkRegion" />
                    </telerik:RadSplitContainer>
                </telerik:RadDocking.DocumentHost>
                  
                <telerik:RadSplitContainer InitialPosition="DockedLeft">
                    <telerik:RadPaneGroup prism:RegionManager.RegionName="NaviRegion" />
                </telerik:RadSplitContainer>
      
            </telerik:RadDocking>
              
        </Grid>
    </Window>

    You can find the MEF Bootstrapper.cs and the RegionAdapter in the post above.
    If you are still having problems, post a small project with your code.

    After you get everything up and running, you will notice that the DataBinding is lost when using RadPaneGroup. Check out the workaround in the following link:
    http://www.telerik.com/community/forums/wpf/docking/databinding-broken-on-radpane-selection-change.aspx


  6. Calabonga
    Calabonga avatar
    29 posts
    Member since:
    Nov 2009

    Posted 08 Feb 2011 Link to this post

    Thanks for the quick replay!
    I've been programming for over 8 years and of course I know about such trifles. The more that we have here a team of developers who also have not been able to advise. The project I can post, but without a database. Unload our project?
  7. George
    Admin
    George avatar
    1332 posts

    Posted 14 Feb 2011 Link to this post

    Hello,

    We will provide an example about how to use RadDocking control with PRISM 4 + MEF in the near future.
     

    All the best,
    George
    the Telerik team
    Let us know about your Windows Phone 7 application built with RadControls and we will help you promote it. Learn more>>
  8. Alan
    Alan avatar
    7 posts
    Member since:
    Sep 2010

    Posted 18 Feb 2011 Link to this post

    Can you please provide the sample as a VB project as well?  Please and thank you!
  9. Binyamin
    Binyamin avatar
    4 posts
    Member since:
    Oct 2010

    Posted 22 Feb 2011 Link to this post

    Hi, do you know when the example should be released?
  10. HDC
    HDC avatar
    214 posts
    Member since:
    Dec 2010

    Posted 05 Apr 2011 Link to this post

    Hi,

    Any idea when the samples will be available? I got it up and running but when I close a RadPane, I'm unable to show it again. A little advice/sample would be more than welcome.


    Thank you very much.

    Peter.
  11. George
    Admin
    George avatar
    1332 posts

    Posted 11 Apr 2011 Link to this post

    Hello,

    Attached you can find the project. This example is very similar to this one, but it is built using MEF. I hope this helps.
     

    Kind regards,
    George
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  12. Joe
    Joe avatar
    15 posts
    Member since:
    Apr 2011

    Posted 31 May 2011 Link to this post

    The attached PRISM_MEF_WPF sample application is NOT helpful.
    First of all, the RadPaneGroupRegionAdapter is never called.  I put break points in there and it is never called.
    There is no [Import] to match the [Export].
    There should be code like this in the Bootstrapper.cs file:

    protected override RegionAdapterMappings ConfigureRegionAdapterMappings() 

    {

      var mappings = base.ConfigureRegionAdapterMappings();

      RadPaneGroupRegionAdapter radPaneGroupRegionAdapter =
        this.Container.GetExportedValue<RadPaneGroupRegionAdapter>("xx.Shell.RadPaneGroupRegionAdapter");

      mappings.RegisterMapping(typeof(RadPaneGroup), radPaneGroupRegionAdapter);

      return mappings;

    }

     

    Secondly, the example uses View Discovery, which is NOT the problem.
    The problem is View Injection and the RadPaneGroup (ItemsControl).
    The problem is that the RadPanes get instantiated but the active one is not the one that the Prism code sets.
    Code like this: regionManager.RequestNavigate does not make the RadPane come to the top.  It comes to the top upon the first call, but as the user navigates between RadPanes in the same radPaneGroup the top RadPane cannot be controlled.
    I cannot get a handle to the RadPane, the View, in the code because MEF_PRISM adds the view to the region with no Name value.  So I cannot find the correct view and make it on top. 

    I sincerely think the RadPaneGroup needs to take the responsibility to make the RadPane on top when the PRISM call regionManager.RequestNavigate is invoked.

    The RegionAdapter is necessary to handle dragging Panes.  I can load RadPane Prism Views into a RadPaneGroup without the RegionAdapter. 

    Please rework this example to use View Injection of multiple views in the same Prism Region and then provide a capability for the user to navigate again to the first view loaded.  Then you will see the difficulty.

    Sincerely, Joe
  13. Joe
    Joe avatar
    15 posts
    Member since:
    Apr 2011

    Posted 02 Jun 2011 Link to this post

    Considerable time was spent working with telerik RadDocking classes.  By following the telerik PRISM_MEF_WPF sample solution and using RadPaneGroup Prism Regions with RadPanes as Prism Views, the capabilities of Prism were broken.  It took several days and team collaboration to determine that the telerik provided example was not good advice.  Instead we are using .NET UserControls inside a RadPaneGroup/RadPane Prism Region.

     

    For example:

    <telerik:RadSplitContainer InitialPosition="DockedTop" telerik:DockingPanel.InitialSize="556,717">

      <telerik:RadPaneGroup IsManipulationEnabled="False">

        <telerik:RadPane BorderThickness="0" 

          VerticalAlignment="Stretch" Margin="0" Height="0" CanUserPin="False" CanUserClose="False" 

          CanFloat="False" IsPinned="True" IsManipulationEnabled="False" PaneHeaderVisibility="Collapsed"

          prism:RegionManager.RegionName="{x:Static inf:RegionNames.WorkAreaRegion}" />

      </telerik:RadPaneGroup>

    </telerik:RadSplitContainer>

     

    The Prism View is created as a .NET UserControl.

    This will allow the NavigationAware and ConfirmNavigationRequest Prism features to work correctly.

  14. George
    Admin
    George avatar
    1332 posts

    Posted 07 Jun 2011 Link to this post

    Hello Joe,

     
    The RadDocking control is a layout control and it creates dynamically panes, pane groups and split containers. This makes difficult to handle all the prism patterns. For example, the panegroup could be set as a region and the views could be registered to this region. The probles comes from the fact that the user can remove the pane from this panegroup and set it to another group that could not be defined as a region (the RadDocking control generates on the fly pane groups and split containers if it is needed). We understand that the current sample has some limitations and we will definitely look for more suitable example for integrating RadDocking control with MEF & PRISM 4.0 because it is very common scenario.

    If you don't create RadPane dynamically, I would suggest placing a content control in each RadPanes in the xaml and define the ContentControls as regions. 


    Greetings,
    George
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  15. Joe
    Joe avatar
    1 posts
    Member since:
    May 2011

    Posted 23 Jun 2011 Link to this post

    Thanks for replying George.

    After some time developing web services and database access and content for views, I am back to navigation.
    I am sorry to say that I cannot get your recommendations to work.  I stand by my previous remarks.  The code does nothing.  It gets loaded but never called.  I tried your suggestion, nesting a ContentControl in the RadPane, but that did nothing either.

    Here is my scenario:

    ShellView:

    - RadDocking
    - RadSplitContainer
    - RadPaneGroup
    - RadPane - Prism Region

    DetailView:

    - UserControl - Injected into the Prism Region

    When the RadPane is hidden the Prism Region is not in the Prism RegionManager.Regions[] collection.
    When the RadPane is docked the Prism Region is in the Prism RegionManager.Regions[] collection.

    When the Prism region is not in the Prism RegionManager.Regions[] collection then my View Injection into that Region fails - obviously.

    Please help me to inject Views into hidden RadPanes.  If I cannot then I have to decide between a prohibition on either RadPanes hiding and docking, or a prohibition on Prism View Injection.  Both are very disappointing choices to take.

    It's my opinion that Prism is a big deal and that Telerik needs to have a Prism test bed and support these reasonable scenarios.

    Sincerely, Joe Kahl

  16. George
    Admin
    George avatar
    1332 posts

    Posted 29 Jun 2011 Link to this post

    Hello Joe,

     

    I understand what is your scenario. To inject a view into a region, you need the region and the view instances. The problem is that when the pane is hidden, the region that is registered is not available in the region manager until gets visible.

    I would suggest injecting the view when the pane is shown. You could handle the RadDocking.Show event that fires every time when a pane is shown and inject the view into the region there(the region is available when the pane is not hidden).

    You can find the attached project. I hope this helps.


    Best wishes,
    George
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  17. Asad
    Asad avatar
    1 posts
    Member since:
    Mar 2012

    Posted 16 Mar 2012 Link to this post

    I am using RadDocking with Prism and MVVM

    My XAML is as follows

    <telerik:RadDocking Grid.Row="2" >
          <telerik:RadDocking.DocumentHost>
            <telerik:RadSplitContainer >
              <telerik:RadPaneGroup region:RegionManager.RegionName="myRegion" >
            </telerik:RadPaneGroup>
            </telerik:RadSplitContainer>
          </telerik:RadDocking.DocumentHost>
     
        </telerik:RadDocking>


    when I use this statement 

    this.regionManager.Regions["myRegion"].RequestNavigate(ViewNames.WidgetsHomeView); 

    it gives me exception that the 

    The region manager does not contain the myRegion region.

    can you kindly let me know why is it so? I was previously using infragistics controls and it was working fine with them.

  18. George
    Admin
    George avatar
    1332 posts

    Posted 21 Mar 2012 Link to this post

    Hi,

    This issue here is tightly related with the Prism framework and usage the RadPaneGroup in the DocumentHost as Region. If you remove the DocumentHost, everything works as expected. I would suggest you to use the RegionManager.SetRegionManager method to register the pane group as region, for example:

    documentHost.SetValue(RegionManager.RegionManagerProperty, regionManager);

    Please, refer to the following forum thread where you can find additional information about this problem - 
    http://www.telerik.com/community/forums/silverlight/docking/documenthost-amp-prism-region.aspx 


    Regards,
    George
    the Telerik team
    Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
  19. Pawel Paluch
    Pawel Paluch avatar
    10 posts
    Member since:
    Mar 2010

    Posted 25 May 2012 Link to this post

    Hello,
    it was quite silent in the topic of RadDocking and MVVM+Prism, but i still have an issue, first of all i use 2011.1.419.40 version and my code is as follows

    RadPaneGroupRegionAdapter.cs
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ComponentModel.Composition;
    using Microsoft.Practices.Prism.Regions;
    using System.Collections.Specialized;
    using Telerik.Windows.Controls;
    using System.Windows.Controls;
     
    namespace nusoft.IndSave.Infrastructure
    {
        [Export]
        public class RadPaneGroupRegionAdapter : RegionAdapterBase<RadPaneGroup>
        {
            [ImportingConstructorAttribute]
            public RadPaneGroupRegionAdapter(IRegionBehaviorFactory regionBehaviourFactory)
                : base(regionBehaviourFactory)
            {
            }
     
            //public RadPaneGroupRegionAdapter(IRegionBehaviorFactory regionBehaviorFactory)
            //    : base(regionBehaviorFactory)
            //{
            //}
     
            protected override void Adapt(IRegion region, RadPaneGroup regionTarget)
            {
                 
                region.ActiveViews.CollectionChanged += (s, e) =>
                {
                    var r = region;
                    switch (e.Action)
                    {
                        case NotifyCollectionChangedAction.Add:
                            foreach (var item in e.NewItems.OfType<RadPane>())
                            {
                                regionTarget.Items.Add(item);
                            }
                            break;
                        case NotifyCollectionChangedAction.Remove:
                            foreach (var item in e.OldItems.OfType<RadPane>())
                            {
                                item.RemoveFromParent();
                            }
                            break;
                        case NotifyCollectionChangedAction.Replace:
                            var oldItems = e.OldItems.OfType<RadPane>();
                            var newItems = e.NewItems.OfType<RadPane>();
                            var newItemsEnumerator = newItems.GetEnumerator();
                            foreach (var oldItem in oldItems)
                            {
                                var parent = oldItem.Parent as ItemsControl;
                                if (parent != null && parent.Items.Contains(oldItem))
                                {
                                    parent.Items[parent.Items.IndexOf(oldItem)] = newItemsEnumerator.Current;
                                    if (!newItemsEnumerator.MoveNext())
                                    {
                                        break;
                                    }
                                }
                                else
                                {
                                    oldItem.RemoveFromParent();
                                    regionTarget.Items.Add(newItemsEnumerator.Current);
                                }
                            }
                            break;
                        //case NotifyCollectionChangedAction.Reset:
                        //    regionTarget
                        //        .EnumeratePanes()
                        //        .ToList()
                        //        .ForEach(p => p.RemoveFromParent());
                        //    break;
                        default:
                            break;
                    }
                };
     
                //foreach (var view in region.Views.OfType<RadPane>())
                //{
                //    regionTarget.Items.Add(view);
                //}
            }
     
     
            protected override IRegion CreateRegion()
            {
                return new AllActiveRegion();
            }
        }
    }

    Bootstrapper.cs (ConfigureRegionAdapterMappings)
    protected override Microsoft.Practices.Prism.Regions.RegionAdapterMappings ConfigureRegionAdapterMappings()
            {
                RegionAdapterMappings mappings = base.ConfigureRegionAdapterMappings();
     
     
     
                mappings.RegisterMapping(typeof(RadPaneGroup), this.Container.GetExportedValue<RadPaneGroupRegionAdapter>());
     
     
     
                return mappings;
            }

    and the way i add regions is:
    1)
    public void NavigateToRegion(string regionName, string viewName)
            {
                RegionManager.RequestNavigate(regionName, viewName, nv =>
                {
                    if (nv.Result == false)
                        RadWindow.Alert(nv.Error.ToString());
                });
            }
    2)
    public void NavigateToRegion(string regionName, object view)
            {
                    RegionManager.AddToRegion(regionName, view);
            }

    second one [2)] behaves as expected, adds view to region every time, it's used to add views to DocumentGroup, and only to it.
    if it comes to first [1)] adds view only once, if RadPane is close, it cannot be added again, which isn't behavior i persue.

    what i noticed is that on region.ActiveViews.CollectionChanged e.Action:=Remove is never fired (same as Replace), what is more closing RadPane does not result in removing view from AllActiveRegion.Views or AllActiveRegion.ActiveViews it is only removed from RadPaneGroup.Items.

    My question is if you came with solution in the meantime, or have any suggestions for workaround, last if you see it as possible to work it out?

    Regards
    Paweł
  20. Pawel Paluch
    Pawel Paluch avatar
    10 posts
    Member since:
    Mar 2010

    Posted 26 May 2012 Link to this post

    Hello again,

    afters spending few long housr with debugger somehow i was able to solve the issue, can provide with working example if anyone requires

    Regards and sorry for bothering
    Paweł
  21. Craig
    Craig avatar
    1 posts
    Member since:
    Feb 2012

    Posted 16 Jul 2012 Link to this post

    Hi Pawel,

    We are using the RadPaneGroup in the same way. I am having the same difficulties as your last post:

    what i noticed is that on region.ActiveViews.CollectionChanged e.Action:=Remove is never fired (same as Replace), what is more closing RadPane does not result in removing view from AllActiveRegion.Views or AllActiveRegion.ActiveViews it is only removed from RadPaneGroup.Items.

    If you conquered these issues, it would save me a lot of debugging if you were to share.

    Thanks
    Craig
  22. Pawel Paluch
    Pawel Paluch avatar
    10 posts
    Member since:
    Mar 2010

    Posted 18 Jul 2012 Link to this post

    Hi Craig,
    alt What you noticed is correct, Pane is only removed from PaneCollection, not the region, thus we have to remove it manually:

    Xaml and CodeBehind

    <telerik:RadDocking Close="RadDocking_Close" >
    ...
    </telerik:RadDocking
    public partial class DockingShellView : Window
        {
            public DockingShellView()
            {
                InitializeComponent();
            }
     
     
            [Import]
            public IRegionManager RegionManager { private get; set; }
     
            private void RadDocking_Close(object sender, Telerik.Windows.Controls.Docking.StateChangeEventArgs e)
            {
                foreach (var pane in e.Panes)
                {
                    foreach (var region in RegionManager.Regions)
                    {
                        if (region.Views.Contains(pane))
                        {
                            region.Remove(pane);
                        }
                    }
                    try
                    {
                        pane.RemoveFromParent();
                    }
                    catch { }
                }
                
            }

     

    RadPaneGroupRegionAdapter:

    [Export]
        public class RadPaneGroupRegionAdapter : RegionAdapterBase<RadPaneGroup>
        {
            [ImportingConstructorAttribute]
            public RadPaneGroupRegionAdapter(IRegionBehaviorFactory regionBehaviourFactory)
                : base(regionBehaviourFactory)
            {
            }
     
            //public RadPaneGroupRegionAdapter(IRegionBehaviorFactory regionBehaviorFactory)
            //    : base(regionBehaviorFactory)
            //{
            //}
     
            protected override void Adapt(IRegion region, RadPaneGroup regionTarget)
            {
                 
                region.ActiveViews.CollectionChanged += (s, e) =>
                {
                    var r = region;
                    switch (e.Action)
                    {
                        case NotifyCollectionChangedAction.Add:
                            foreach (var item in e.NewItems.OfType<RadPane>())
                            {
                                item.IsHidden = false;
                                if (item.Parent != null)
                                {
                                    item.RemoveFromParent();
                                }
     
                                regionTarget.Items.Add(item);
                            }
                            break;
                        case NotifyCollectionChangedAction.Remove:
                            foreach (var item in e.OldItems.OfType<RadPane>())
                            {
                                item.RemoveFromParent();
                                try
                                {
                                    item.PaneGroup.RemovePane(item);
                                }
                                catch { }
                            }
                            break;
                        case NotifyCollectionChangedAction.Replace:
                            var oldItems = e.OldItems.OfType<RadPane>();
                            var newItems = e.NewItems.OfType<RadPane>();
                            var newItemsEnumerator = newItems.GetEnumerator();
                            foreach (var oldItem in oldItems)
                            {
                                var parent = oldItem.Parent as ItemsControl;
                                if (parent != null && parent.Items.Contains(oldItem))
                                {
                                    parent.Items[parent.Items.IndexOf(oldItem)] = newItemsEnumerator.Current;
                                    if (!newItemsEnumerator.MoveNext())
                                    {
                                        break;
                                    }
                                }
                                else
                                {
                                    oldItem.RemoveFromParent();
                                    regionTarget.Items.Add(newItemsEnumerator.Current);
                                }
                            }
                            break;
                        //case NotifyCollectionChangedAction.Reset:
                        //    regionTarget
                        //        .EnumeratePanes()
                        //        .ToList()
                        //        .ForEach(p => p.RemoveFromParent());
                        //    break;
                        default:
                            break;
                    }
                };
     
                //foreach (var view in region.Views.OfType<RadPane>())
                //{
                //    regionTarget.Items.Add(view);
                //}
            }
     
     
            protected override IRegion CreateRegion()
            {
                return new AllActiveRegion();
            }
        }

    you may wonder why

    item.IsHidden = false;
                                if (item.Parent != null)
                                {
                                    item.RemoveFromParent();
                                }
     
                                regionTarget.Items.Add(item);

    would be necessary

    i noticed strange bahavior, propbly you'll see same on debugger.
    after RadPane is closed it's also hidden, thus item.IsHidden=false;, what is strange that  whis SET couses item.Parent to be set as well, which leads to problem if RadPane was dragged from original position to elsewhere

     

  23. Erik
    Erik avatar
    43 posts
    Member since:
    Jan 2011

    Posted 31 Oct 2012 Link to this post

    Hi Craig and Pawel -

    We are just getting started with this, so your code samples and discussion have been absolutely great to help understanding it.  A question I was wondering about is what exactly are the views you are navigating to in the document host?

    I started out with a UserControl at first, and now am trying to change that to a RadDocumentPane but am getting an error that says "ContextMenuTemplate should contain a RadContextMenu as root element".  If you could post the XAML header and your class declaration lines for a sample view that should resolve the issue. 

    Thanks and sorry if this seems a basic question.
    Erik
  24. Erik
    Erik avatar
    43 posts
    Member since:
    Jan 2011

    Posted 31 Oct 2012 Link to this post

    I just figured out that this was a XAML design viewer error within Visual Studio -- and worked fine at runtime and compile.  I will post a separate question to the forums regarding the XAML designer.  Thanks for the great info on the post!
  25. abdul rahman
    abdul rahman avatar
    7 posts
    Member since:
    Sep 2004

    Posted 10 Dec 2012 Link to this post

    Hi,

    Appreciate if you could provide me with the Sample you mentioned.

    Thanks in advance

    AR
  26. Yu
    Yu avatar
    17 posts
    Member since:
    Jul 2012

    Posted 14 Jan 2013 Link to this post

    Any progress or sample projects?

    has anything been done to the behavior described by george?

    -------------------------------------

    Posted on Jun 29, 2011

    Hello Joe,

     

    I understand what is your scenario. To inject a view into a region, you need the region and the view instances. The problem is that when the pane is hidden, the region that is registered is not available in the region manager until gets visible.

    I would suggest injecting the view when the pane is shown. You could handle the RadDocking.Show event that fires every time when a pane is shown and inject the view into the region there(the region is available when the pane is not hidden).

    You can find the attached project. I hope this helps.


    Best wishes,
    George
    the Telerik team

    --------------------------------

    I posted a releatd question here

    http://www.telerik.com/community/forums/wpf/docking/telerik-raddocking-vs-prism-problems.aspx#2446661



    Thanks
  27. George
    Admin
    George avatar
    1332 posts

    Posted 18 Jan 2013 Link to this post

    Hello,

    You can find my answer here - http://www.telerik.com/community/forums/wpf/docking/telerik-raddocking-vs-prism-problems.aspx#2446661 

    All the best,
    George
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

  28. Kristoffer
    Kristoffer avatar
    158 posts
    Member since:
    Dec 2012

    Posted 21 Jan 2013 Link to this post

    PRISM 4 + MEF + MVVM. How do I specify the title of the docking pane when I do this?

    <telerik:RadPaneGroup prism:RegionManager.RegionName="{x:Static appcommon:Regions.MyRegion}" />

    This somehow creates a new pane. Where does that occur? I obviously need to set the caption etc.

    In an ideal world, I would do the following. It makes sense to define groups in XAML, and let plugins populate a certain pane inside the group:

    <telerik:RadPaneGroup>
      <telerik:RadPane prism:RegionManager.RegionName="{x:Static appcommon:Regions.MyRegion}" Header="MyData" CanUserClose="False" IsPinned="False" telerik:RadDocking.SerializationTag="MyPane">
       ...
    </telerik:RadPaneGroup>

    That doesn't work. Is it possible to create an adapter for RadPane too?
  29. George
    Admin
    George avatar
    1332 posts

    Posted 24 Jan 2013 Link to this post

    Hello,

    You could refer to the following blog post for more information how the PaneGroupAdapter in PRISM example works - http://blogs.telerik.com/xamlteam/posts/09-08-31/using-the-raddocking-control-with-prism.aspx.

    As you note, the RadPane can be set as a region in the same way as a ContentControl. In  this case, the PaneGroupAdapter is not required.

    All the best,
    George
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

Back to Top
UI for WPF is Visual Studio 2017 Ready