Skip to content

Instantly share code, notes, and snippets.

@leemean
Created March 25, 2019 07:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leemean/fca175ab6ff6ca707df459c1c51af696 to your computer and use it in GitHub Desktop.
Save leemean/fca175ab6ff6ca707df459c1c51af696 to your computer and use it in GitHub Desktop.
DockingManagerBehavior
using APS.Infrastructure.MVVM;
using APS.Infrastructure.ViewBase;
using APS.Views;
using DevExpress.Xpf.Docking;
using Prism.Regions;
using Prism.Regions.Behaviors;
using System;
using System.Collections.Specialized;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
namespace APS.RegionAdapters
{
/// <summary>
/// Encapsulates behaviours related to the docking manager, keeping
/// the documents source in sync with the active views of the <see cref="IRegion"/>.
/// </summary>
public class DockingManagerBehavior : RegionBehavior, IHostAwareRegionBehavior
{
private DockLayoutManager dockingManager;
/// <summary>
/// The target control for the <see cref="IRegion"/>.
/// </summary>
public DependencyObject HostControl
{
get
{
return dockingManager;
}
set
{
dockingManager = value as DockLayoutManager;
}
}
/// <summary>
/// The DockingManagerBehavior's key used to
/// identify it in the region's behavior collection.
/// </summary>
public static readonly string BehaviorKey = "DockingManagerBehavior";
/// <summary>
/// Register to handle region events.
/// </summary>
protected override void OnAttach()
{
Region.ActiveViews.CollectionChanged += ActiveViewsCollectionChanged;
Region.Views.CollectionChanged += ViewsCollectionChanged;
if(dockingManager != null)
{
dockingManager.DockItemClosed += DockingManager_DockItemClosed;
}
}
/// <summary>
/// Removes the document from the <see cref="IRegion"/> after it has been closed.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">DockItem closed event arguments.</param>
private void DockingManager_DockItemClosed(object sender, DevExpress.Xpf.Docking.Base.DockItemClosedEventArgs e)
{
var panel = e.Item as DocumentPanel;
if (panel == null)
{
return;
}
var view = panel.Content as DocumentViewBase;
if (Region.Views.Contains(view))
{
view.CloseDocument();
//Region.RegionManager.Regions["DocumentRegion"].Remove(view);
Region.RegionManager.Regions["DocumentRegion"].Remove(view);
}
}
/// <summary>
/// Handles changes to the <see cref="IRegion"/> views collection, adding
/// or removing items to the <see cref="HostControl"/> document source.
/// </summary>
/// <param name="sender">The <see cref="IRegion"/> views collection.</param>
/// <param name="e">Event arguments.</param>
private void ViewsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
foreach (object newItem in e.NewItems)
{
var documentViewBase = newItem as IViewBase;
if (documentViewBase != null)
{
documentViewBase.HostControl = dockingManager;
string viewKeyName = "k_" + documentViewBase.GetType().Name;
documentViewBase.Key = viewKeyName;
string caption = (documentViewBase.GetType().GetCustomAttributes(true).FirstOrDefault(p => p is ViewNameAnnotation)
as ViewNameAnnotation)?.Name;
documentViewBase.Caption = caption;
if(documentViewBase.DataContext != null)
{
var viewModel = documentViewBase.DataContext as NavigationAware;
viewModel.Activate += ViewModel_Activate;
}
////如果打开的view是documentviewbase
//if (documentViewBase is DocumentViewBase)
//{
// //获取document里面所有module的view,然后加载config
// var views = (documentViewBase as DocumentViewBase).Views;
// foreach(var item in views)
// {
// if (item is IConfigableView)
// {
// (item as IConfigableView).ApplyConfiguration(new Newtonsoft.Json.Linq.JObject());
// (item as IConfigableView).ConfigComplete();
// }
// if (item.DataContext is IConfigableViewModel)
// {
// (item.DataContext as IConfigableViewModel).ApplyConfiguration(new Newtonsoft.Json.Linq.JObject());
// (item.DataContext as IConfigableViewModel).ConfigComplete();
// }
// }
//}
////如果打开的view是单个view
//else
//{
// if (documentViewBase is IConfigableView)
// {
// (documentViewBase as IConfigableView).ApplyConfiguration(new Newtonsoft.Json.Linq.JObject());
// (documentViewBase as IConfigableView).ConfigComplete();
// }
// if (documentViewBase.DataContext is IConfigableViewModel)
// {
// (documentViewBase.DataContext as IConfigableViewModel).ApplyConfiguration(new Newtonsoft.Json.Linq.JObject());
// (documentViewBase.DataContext as IConfigableViewModel).ConfigComplete();
// }
//}
//string id = Guid.NewGuid().ToString().Replace("-", "");
DocumentGroup documentGroup = dockingManager.GetItem("Documents") as DocumentGroup;
DocumentPanel document = new DocumentPanel
{
Caption = caption,
Content = documentViewBase,
Name = viewKeyName
};
documentGroup.Add(document);
dockingManager.ActiveLayoutItem = document;
document.IsActive = true;
documentViewBase.IsActive = true;
}
}
}
}
private void ViewModel_Activate(object sender, EventArgs e)
{
var group = dockingManager.GetItem("Documents") as DocumentGroup;
var selectItem = group.Items
.FirstOrDefault(p => p.Name == (sender as BaseViewModel).Key);
if (selectItem != null)
{
group.SelectedTabIndex = group.Items.IndexOf(selectItem);
selectItem.IsActive = true;
}
}
/// <summary>
/// Keeps the active content of the <see cref="IRegion"/> in sync with the <see cref="HostControl"/>.
/// </summary>
/// <param name="sender">The <see cref="IRegion"/> views collection.</param>
/// <param name="e">Event arguments.</param>
private void ActiveViewsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
var currtView = (dockingManager.ActiveLayoutItem as DocumentPanel).Content as IViewBase;
if (currtView != null
&& currtView != e.NewItems[0]
&& Region.ActiveViews.Contains(currtView)
)
{
currtView.IsActive = false;
Region.Deactivate(currtView);
}
dockingManager.ActiveLayoutItem = e.NewItems[0] as BaseLayoutItem;
}
else if (e.Action == NotifyCollectionChangedAction.Remove)
{
var currtView = (dockingManager.ActiveLayoutItem as DocumentPanel).Content as IViewBase;
if(e.OldItems.Contains(currtView))
{
currtView.IsActive = false;
dockingManager.ActiveLayoutItem = null;
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment