首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >根据选定/加载的模块插入/导航RibbonTabItems

根据选定/加载的模块插入/导航RibbonTabItems
EN

Stack Overflow用户
提问于 2013-08-07 00:09:17
回答 1查看 585关注 0票数 0

我遇到了以下问题:

在外壳中有一个带状区域,我们称它为"ShellRibbonRegion“。还有一个任务按钮区域"ShellTaskButtonRegion“(similar to Creating View-Switching Applications with Prism 4)。

例如,有三个模块。每个模块都有不同数量的RibbonTabItems。模块1有一个RibbonTabItem,模块2有四个,模块3有一个。

现在的目标是在单击模块的"TaskButton“后将RibbonTabItems添加到"ShellRibbonRegion”中。我已经编写了一个自定义RegionAdapter,但问题是要么只显示一个RibbonTabItem (SingleActiveRegion),要么显示来自所有模块的所有(AllActiveRegion) RibbonTabItems。

代码语言:javascript
复制
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();
    }
}

所需的行为如下:

一个模块的"TaskButton“被点击:所有不属于该模块的RibbonTabItems将从区域中移除,并添加来自”已点击“模块的标签项。

我怎样才能实现这个行为呢?

EN

回答 1

Stack Overflow用户

发布于 2014-05-21 23:30:40

我也遇到了类似的问题,最终只能跟踪以模块类型名称为关键字的哈希表中添加的选项卡。模块选项卡是在包含功能区控件的模块视图中开发的,因此还需要传输数据上下文。下面是我最终使用的RibbonRegionAdapter (添加您自己的命名空间!):

代码语言:javascript
复制
// 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();
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18085229

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档