using System;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Configuration;
using System.Globalization;
using System.Linq;
using DTS.Common.Classes;
using DTS.Common.Enums;
using DTS.Common.Events;
using DTS.Common.Base;
using Prism.Events;
using Prism.Regions;
using Microsoft.Windows.Controls.Ribbon;
//https://fluent.codeplex.com/SourceControl/latest
namespace DTS.Common.RibbonControl
{
///
/// Enables use of the in a Prism .
/// To install Ribbon Controls Library, run the following command in the Package Manager Console - Install-Package RibbonControlsLibrary
/// or install from https://www.microsoft.com/en-us/download/details.aspx?id=11877
///
///
/// The adapts controls derived from the class such as .
///
public class RibbonRegionAdapter : RegionAdapterBase, IDisposable
{
///
/// Injected region manager
///
private readonly IRegionManager _regionManager;
///
/// Injected event aggregator
///
private readonly IEventAggregator _eventAggregator;
private static readonly object Lock = new object();
///
/// Creates a new instance of the class.
///
/// Allows the registration of the default set of RegionBehaviors.
/// Obtained reference of the region manager by using dependency injection.
/// Obtained reference of the revent aggregator by using dependency injection.
public RibbonRegionAdapter(IRegionBehaviorFactory regionBehaviorFactory, IRegionManager regionManager, IEventAggregator eventAggregator)
: base(regionBehaviorFactory)
{
_regionManager = regionManager;
_eventAggregator = eventAggregator;
_eventAggregator.GetEvent().Subscribe(OnTabControlSelectionChanged);
}
///
/// Adapts the to an .
///
/// The new region being used.
/// The object to adapt.
protected override void Adapt(IRegion region, Ribbon regionTarget)
{
if (regionTarget == null)
throw new ArgumentNullException("regionTarget");
region.ActiveViews.CollectionChanged += (o, e) =>
{
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
foreach (var item in e.NewItems.OfType())
AddRibbonTabToRegion(item, regionTarget);
foreach (var item in e.NewItems.OfType())
AddApplicationMenuToRegion(item, regionTarget);
break;
case NotifyCollectionChangedAction.Remove:
foreach (var item in e.OldItems.OfType())
RemoveRibbonTabFromRibbonRegion(item, regionTarget);
break;
}
};
}
private void AddRibbonTabToRegion(RibbonTab ribbonTab, Ribbon regionTarget)
{
lock (Lock)
{
if (string.IsNullOrEmpty(ribbonTab.Uid))
ribbonTab.Uid = Guid.NewGuid().GetHashCode().ToString(CultureInfo.InvariantCulture);
regionTarget.Items.Add(ribbonTab);
}
regionTarget.Items.SortDescriptions.Add(new SortDescription("TabIndex", ListSortDirection.Ascending));
var config = ConfigurationManager.AppSettings["DefaultRibbonTab"];
if (!string.IsNullOrWhiteSpace(config))
{
ribbonTab.IsSelected = ribbonTab.Header.ToString().ToLower() == config.ToLower();
}
}
private void AddApplicationMenuToRegion(RibbonApplicationMenu applicationMenu, Ribbon regionTarget)
{
if (string.IsNullOrEmpty(applicationMenu.Uid))
applicationMenu.Uid = Guid.NewGuid().GetHashCode().ToString(CultureInfo.InvariantCulture);
regionTarget.ApplicationMenu = applicationMenu;
}
private void RemoveRibbonTabFromRibbonRegion(RibbonTab ribbonTab, Ribbon regionTarget)
{
regionTarget.Items.Remove(ribbonTab);
}
private void OnTabControlSelectionChanged(TabControlSelectionEventArgs e)
{
if (e.Operation == TabControlOperation.RemovedItem) return;
var view = e.Item as IBaseView;
if (view == null) return;
if (view.DataContext == null) return;
var ribbonTabInfo = view.DataContext as IRibbonTabInfoProvider;
if (ribbonTabInfo == null) return;
if (string.IsNullOrEmpty(ribbonTabInfo.RibbonTabUid)) return;
var currentTab = _regionManager.Regions[RegionNames.RibbonRegion].ActiveViews.OfType().FirstOrDefault(t => t.IsSelected);
if (currentTab == null) return;
if (ribbonTabInfo.RibbonTabUid != currentTab.Uid)
{
var selectedTab = _regionManager.Regions[RegionNames.RibbonRegion].ActiveViews.OfType().FirstOrDefault(t => t.Uid == ribbonTabInfo.RibbonTabUid);
if (selectedTab != null)
selectedTab.IsSelected = true;
}
}
///
/// Template method to create a new instance of
/// that will be used to adapt the object.
///
///
/// A new instance of .
///
protected override IRegion CreateRegion()
{
return new AllActiveRegion();
}
#region IDisposable Support
private bool _disposedValue; // To detect redundant calls.
///
/// Disposes the object.
///
/// True if called by the public Dispose method.
protected virtual void Dispose(bool disposing)
{
if (!_disposedValue)
{
if (_eventAggregator != null)
_eventAggregator.GetEvent().Unsubscribe(OnTabControlSelectionChanged);
}
_disposedValue = true;
}
///
/// Disposes the object.
///
public void Dispose()
{
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose(true);
GC.SuppressFinalize(this);
}
///
/// Object finalizer.
///
~RibbonRegionAdapter()
{
Dispose(false);
}
#endregion
}
}