C# 根据所选/加载的模块插入/导航Ribbontabitem
我有以下问题: 外壳中有一个带状区域,我们称之为“ShellRibbonRegion”。还有一个任务按钮区域“ShellTaskButtonRegion”() 例如,有三个模块。每个模块都有不同数量的Ribbontabitem。模块1有一个RibbonTabItem,模块2有四个,模块3有一个 现在的目标是在单击模块的“TaskButton”后,将Ribbontabitem添加到“ShellRibbonRegion”。我已经编写了一个自定义RegionAdapter,但问题是要么只显示一个RibbontaItem(SingleActiveRegion),要么显示所有模块中的所有RibbontaItem(AllActiveRegion)C# 根据所选/加载的模块插入/导航Ribbontabitem,c#,wpf,prism,ribbon,C#,Wpf,Prism,Ribbon,我有以下问题: 外壳中有一个带状区域,我们称之为“ShellRibbonRegion”。还有一个任务按钮区域“ShellTaskButtonRegion”() 例如,有三个模块。每个模块都有不同数量的Ribbontabitem。模块1有一个RibbonTabItem,模块2有四个,模块3有一个 现在的目标是在单击模块的“TaskButton”后,将Ribbontabitem添加到“ShellRibbonRegion”。我已经编写了一个自定义RegionAdapter,但问题是要么只显示一个Rib
public class RibbonRegionAdapter : RegionAdapterBase<Ribbon>
{
/// <summary>
/// Default constructor.
/// </summary>
/// <param name="behaviorFactory">Allows the registration of the default set of RegionBehaviors.</param>
public RibbonRegionAdapter(IRegionBehaviorFactory behaviorFactory)
: base(behaviorFactory)
{
}
/// <summary>
/// Adapts a WPF control to serve as a Prism IRegion.
/// </summary>
/// <param name="region">The new region being used.</param>
/// <param name="regionTarget">The WPF control to adapt.</param>
protected override void Adapt(IRegion region, Ribbon regionTarget)
{
regionTarget.SelectedTabChanged += (sender, args) =>
{
if (regionTarget.SelectedTabItem == null)
return;
//region.Activate(regionTarget.SelectedTabItem);
};
region.Views.CollectionChanged += (sender, e) =>
{
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
foreach (UIElement element in e.NewItems)
{
if(element is Ribbon)
this.AddRibbon(element as Ribbon, regionTarget, region);
else if(element is RibbonTabItem)
this.AddRibbonTabItem(element as RibbonTabItem, regionTarget, region);
else if(element is Backstage)
this.AddBackstage(element as Backstage, regionTarget);
}
break;
case NotifyCollectionChangedAction.Remove:
foreach (UIElement elementLoopVariable in e.OldItems)
{
var element = elementLoopVariable;
if (element is Ribbon)
this.RemoveRibbon(element as Ribbon, regionTarget);
else if (element is RibbonTabItem)
this.RemoveRibbonTabItem(element as RibbonTabItem, regionTarget);
else if (element is Backstage)
this.RemoveBackstage(element as Backstage, regionTarget);
}
break;
}
};
}
#region Add
private void AddRibbon(Ribbon ribbon, Ribbon targetRibbon, IRegion region)
{
//Add tabs
foreach (var ribbonTabItem in ribbon.Tabs)
{
this.AddRibbonTabItem(ribbonTabItem, targetRibbon, region);
}
}
private void AddRibbonTabItem(RibbonTabItem ribbonTabItem, Ribbon targetRibbon, IRegion region)
{
if (!targetRibbon.Tabs.Contains(ribbonTabItem))
targetRibbon.Tabs.Add(ribbonTabItem);
}
private void AddBackstage(Backstage backstage, Ribbon targetRibbon)
{
}
#endregion
#region Remove
private void RemoveRibbon(Ribbon ribbon, Ribbon targetRibbon)
{
var tmp = new List<RibbonTabItem>(ribbon.Tabs);
//Add tabs
foreach (var ribbonTabItem in tmp)
{
if (targetRibbon.Tabs.Contains(ribbonTabItem)) this.RemoveRibbonTabItem(ribbonTabItem, targetRibbon);
}
}
private void RemoveRibbonTabItem(RibbonTabItem ribbonTabItem, Ribbon targetRibbon)
{
if (ribbonTabItem is IRegionMemberLifetime)
{
var rml = (IRegionMemberLifetime)ribbonTabItem;
if (!rml.KeepAlive) targetRibbon.Tabs.Remove(ribbonTabItem);
return;
}
targetRibbon.Tabs.Remove(ribbonTabItem);
}
private void RemoveBackstage(Backstage backstage, Ribbon targetRibbon)
{
}
#endregion
protected override IRegion CreateRegion()
{
return new AllActiveRegion();
}
}
公共类RibbonRegionaAdapter:RegionaAdapterBase
{
///
///默认构造函数。
///
///允许注册默认的RegionBehavior集合。
公共Ribbon区域适配器(IRegionBehaviorFactory行为工厂)
:base(行为工厂)
{
}
///
///调整WPF控件以用作棱镜区域。
///
///正在使用的新区域。
///WPF控件将进行调整。
受保护的覆盖无效调整(IRegion区域、Ribbon区域目标)
{
regionTarget.SelectedTabChanged+=(发件人,参数)=>
{
如果(regionTarget.SelectedTabItem==null)
返回;
//region.Activate(regionTarget.SelectedTabItem);
};
region.Views.CollectionChanged+=(发件人,e)=>
{
开关(电动)
{
案例NotifyCollectionChangedAction。添加:
foreach(e.NewItems中的UIElement)
{
如果(元素为Ribbon)
this.AddRibbon(元素为Ribbon、regionTarget、region);
else if(元素为RibbonTabItem)
addRibbontaItem(元素为RibbontaItem、regionTarget、region);
else if(元素为后台)
this.AddBackstage(元素为Backstage,regionTarget);
}
打破
案例NotifyCollectionChangedAction。删除:
foreach(e.OldItems中的UIElement elementLoopVariable)
{
var元素=elementLoopVariable;
如果(元素为Ribbon)
此.Remobilibbon(元素为Ribbon,regionTarget);
else if(元素为RibbonTabItem)
此.RemobilibbontAbItem(元素为RibbonTabItem、regionTarget);
else if(元素为后台)
此.RemoveBackstage(元素为Backstage,regionTarget);
}
打破
}
};
}
#区域添加
专用void AddRibbon(Ribbon Ribbon、Ribbon targetRibbon、IRegion区域)
{
//添加选项卡
foreach(ribbon.Tabs中的var ribbonTabItem)
{
AddRibbonTabItem(ribbonTabItem,targetRibbon,region);
}
}
私有void addRibbontaItem(RibbontaItem RibbontaItem,RibbontaItem,Ribbon目标,IRegion区域)
{
如果(!targetRibbon.Tabs.Contains(ribbonTabItem))
Tabs.Add(ribbonTabItem);
}
私人后台(后台后台,Ribbon targetRibbon)
{
}
#端区
#区域删除
专用空心清除器IBBON(Ribbon Ribbon,Ribbon targetRibbon)
{
var tmp=新列表(ribbon.Tabs);
//添加选项卡
foreach(tmp中的var ribbonTabItem)
{
如果(targetlibon.Tabs.Contains(ribbonTabItem))此.RemoveibbontabItem(ribbonTabItem,targetlibon);
}
}
专用void RemobileIBBontabItem(RibbonTabItem RibbonTabItem,Ribbon targetRibbon)
{
如果(RibbontaItem为IRegionMemberLifetime)
{
var rml=(IRegionMemberLifetime)RibbontaItem;
如果(!rml.KeepAlive)targetRibbon.Tabs.Remove(ribbonTabItem);
返回;
}
Tabs.移除(ribbonTabItem);
}
私人无效移除后台(后台后台,Ribbon targetRibbon)
{
}
#端区
受保护的覆盖IRegion CreateRegion()
{
返回新的AllActiveRegion();
}
}
期望的行为如下:
单击模块的“任务按钮”:从区域中删除不属于此模块的所有Ribbontabitem,并添加“单击”模块中的选项卡项
如何实现这种行为?我遇到了类似的问题,并最终跟踪添加在由模块类型名称键入的哈希表中的选项卡。模块选项卡是在包含功能区控件的模块视图中开发的,因此还需要传输datacontext。以下是我的RibbonRegionaAdapter(添加您自己的名称空间!):
//基于
// http://www.codeproject.com/Articles/165370/Creating-View-Switching-Applications-with-Prism-4#AppendixA
//经过我的修改。
///
///允许将功能区控件用作棱柱区域。
///
///请参阅Microsoft Prism开发人员指南(第4版),第页。189
[出口]
公共类RibbonRegionaAdapter:RegionaAdapterBase{
私有静态只读哈希表RibbonTabs=新哈希表();
///
///默认构造函数。
///
///允许注册
///区域行为的默认集合。
[导入构造函数]
公共Ribbon区域适配器(IRegionBehaviorFactory行为工厂)
:base(行为工厂){}
///
///调整WPF控件以用作棱镜区域。
///
///正在使用的新区域。
///WPF控件将进行调整。
受保护的覆盖无效调整(IRegion区域、Ribbon区域目标){
region.Views.CollectionChanged+=(发件人,e)=>{
开关(电动){
案例报告
// Based on
// http://www.codeproject.com/Articles/165370/Creating-View-Switching-Applications-with-Prism-4#AppendixA
// with my modifications.
/// <summary>
/// Enables use of a Ribbon control as a Prism region.
/// </summary>
/// <remarks> See Developer's Guide to Microsoft Prism (Ver. 4), p. 189.</remarks>
[Export]
public class RibbonRegionAdapter : RegionAdapterBase<Ribbon> {
private static readonly Hashtable RibbonTabs = new Hashtable();
/// <summary>
/// Default constructor.
/// </summary>
/// <param name="behaviorFactory">Allows the registration
/// of the default set of RegionBehaviors.</param>
[ImportingConstructor]
public RibbonRegionAdapter(IRegionBehaviorFactory behaviorFactory)
: base(behaviorFactory) {}
/// <summary>
/// Adapts a WPF control to serve as a Prism IRegion.
/// </summary>
/// <param name="region">The new region being used.</param>
/// <param name="regionTarget">The WPF control to adapt.</param>
protected override void Adapt(IRegion region, Ribbon regionTarget) {
region.Views.CollectionChanged += (sender, e) => {
switch (e.Action) {
case NotifyCollectionChangedAction.Add:
foreach (FrameworkElement element in e.NewItems) {
if (element is Ribbon) {
Ribbon rb = element as Ribbon;
var tabList = new List<RibbonTab>();
var items = rb.Items;
for (int i = rb.Items.Count - 1; i >= 0; i--) {
if (!(rb.Items[i] is RibbonTab)) continue;
RibbonTab rt = (rb.Items[i] as RibbonTab);
rb.Items.Remove(rt); // remove from existing view ribbon
regionTarget.Items.Add(rt); // add to target region ribbon
tabList.Add(rt); // add to tracking list
// Without these next 3 lines the tabs datacontext would end up being inherited from the Ribbon to which
// it has been transferred.
// Not sure if this is the best place to do this but it works for my purposes at the moment
if (rt.DataContext.Equals(regionTarget.DataContext)) { // then it is inherited
rt.DataContext = rb.DataContext; // so set it explicitly to the original parent ribbons datacontext
}
}
// store tracking list in hashtable using string key (= the view type name)
var key = rb.GetType().Name;
RibbonTabs[key] = tabList;
} else if (element is RibbonTab) {
// the datacontext should already be set in these circumstances
regionTarget.Items.Add(element);
}
}
break;
case NotifyCollectionChangedAction.Remove:
foreach (UIElement elementLoopVariable in e.OldItems) {
var element = elementLoopVariable;
if (element is Ribbon) {
Ribbon rb = element as Ribbon;
var key = rb.GetType().Name;
if (!RibbonTabs.ContainsKey(key)) continue; // no ribbon tabs have been tracked
var tabList = (RibbonTabs[key] as List<RibbonTab>) ?? new List<RibbonTab>();
foreach (RibbonTab rt in tabList)
{
if (!regionTarget.Items.Contains(rt)) continue; // this shouldn't happen
regionTarget.Items.Remove(rt); // remove from target region ribbon
rb.Items.Add(rt); // restore to view ribbon
}
RibbonTabs.Remove(key); // finished tracking so remove from hashtable
} else if (regionTarget.Items.Contains(element)) {
regionTarget.Items.Remove(element);
}
}
break;
}
};
}
protected override IRegion CreateRegion() {
return new SingleActiveRegion();
}
}