首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >棱镜:在一个区域中堆叠控件?

棱镜:在一个区域中堆叠控件?
EN

Stack Overflow用户
提问于 2011-02-09 21:09:20
回答 6查看 3.7K关注 0票数 4

我的Prism应用程序需要将按钮从几个模块插入到Shell区域。这些按钮将垂直堆叠,就像Outlook 2010中的导航按钮(邮件、日历等)一样。我使用自定义控件作为按钮,所以我不需要担心模板问题--我的问题与插入普通单选按钮是一样的。

如何设置区域,使按钮垂直堆叠显示?谢谢你的帮助。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2011-02-09 21:26:45

当考虑垂直堆叠项目时,StackPanel会立即跳到脑海中。不幸的是,Prism不支持StackPanel作为一个开箱即用的区域。幸运的是,您可以创建一个RegionAdapter来解决这个问题。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Public Class StackPanelRegionAdapter
Inherits RegionAdapterBase(Of StackPanel)

    Public Sub New(ByVal behaviorFactory As IRegionBehaviorFactory)
        MyBase.New(behaviorFactory)
    End Sub

    Protected Overrides Sub Adapt(ByVal region As IRegion, ByVal regionTarget As StackPanel)
        AddHandler region.Views.CollectionChanged, Sub(sender As Object, e As NotifyCollectionChangedEventArgs)
            If e.Action = NotifyCollectionChangedAction.Add Then
                For Each element As FrameworkElement In e.NewItems
                    regionTarget.Children.Add(element)
                Next
            Else
            If e.Action = NotifyCollectionChangedAction.Remove Then
                For Each element In e.OldItems
                    If regionTarget.Children.Contains(element) Then
                        regionTarget.Children.Remove(element)
                    End If
                Next
            End If
        End Sub
    End Sub

    Protected Overrides Function CreateRegion() As Microsoft.Practices.Prism.Regions.IRegion
        Return New AllActiveRegion
    End Function
End Class

在此基础上,您只需在引导程序中的ConfigureRegionAdapterMappings覆盖中添加映射。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Protected Overrides Function ConfigureRegionAdapterMappings() As Microsoft.Practices.Prism.Regions.RegionAdapterMappings
    Dim mappings = MyBase.ConfigureRegionAdapterMappings()
    mappings.RegisterMapping(GetType(Grid), Container.Resolve(Of PrismExtensions.GridRegionAdapter))
    mappings.RegisterMapping(GetType(StackPanel), Container.Resolve(Of PrismExtensions.StackPanelRegionAdapter))
    Return mappings
End Function

编辑:找到我最初获得代码的John Papa链接。(在C#中,如果您正在使用它) Fill My Prism Region, Please

票数 6
EN

Stack Overflow用户

发布于 2011-02-09 22:37:40

Matt的解决方案在“微软棱镜开发人员指南”(V4)第189-191页进行了解释。

对于研究这个问题的C#开发人员,这里是Matt的适配器到C#的转换:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using System.Collections.Specialized;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Practices.Prism.Regions;

namespace FsNoteMaster3.Shell.Views.Utility
{
    /// <summary>
    /// Enables use of a StackPanel in a Prism region.
    /// </summary>
    /// <remarks> See stackoverflow.com/questions/4950464/prism-stacking-controls-in-a-region</remarks>
    public class StackPanelRegionAdapter : RegionAdapterBase<StackPanel>
    {
        /// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="behaviorFactory">Allows the registration of the default set of RegionBehaviors.</param>
        public StackPanelRegionAdapter(IRegionBehaviorFactory behaviorFactory) : base(behaviorFactory)
        {
        }

        /// <summary>
        /// Adapts a ContentControl to an IRegion. 
        /// </summary>
        /// <param name="region">The new region being used.</param>
        /// <param name="regionTarget">The object to adapt.</param>
        protected override void Adapt(IRegion region, StackPanel regionTarget)
        {
            region.Views.CollectionChanged += (sender, e) =>
            {
                switch (e.Action)
                {
                    case NotifyCollectionChangedAction.Add:
                        foreach (FrameworkElement element in e.NewItems) 
                        {
                            regionTarget.Children.Add(element);
                        }
                        break;

                    case NotifyCollectionChangedAction.Remove:
                        foreach (UIElement elementLoopVariable in e.OldItems) 
                        {
                            var element = elementLoopVariable;
                            if (regionTarget.Children.Contains(element)) 
                            {
                                regionTarget.Children.Remove(element);
                            }
                        }
                        break;
                }
            };
        }

        /// <summary>
        /// Template method to create a new instance of IRegion that will be used to adapt the object. 
        /// </summary>
        /// <returns>A new instance of IRegion.</returns>
        protected override Microsoft.Practices.Prism.Regions.IRegion CreateRegion()
        {
            return new AllActiveRegion();
        }
    }
}

对于Bootstrapper,这里是C#中的ConfigureRegionAdapterMappings()覆盖,针对Prism 4进行了更新:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/// <summary>
/// Configures the default region adapter mappings to use in the application.
/// </summary>
/// <returns>The RegionAdapterMappings instance containing all the mappings.</returns>
protected override RegionAdapterMappings ConfigureRegionAdapterMappings()
{
    var mappings = base.ConfigureRegionAdapterMappings();
    mappings.RegisterMapping(typeof(StackPanel), ServiceLocator.Current.GetInstance<StackPanelRegionAdapter>());
    return mappings;
}
票数 6
EN

Stack Overflow用户

发布于 2011-02-10 18:54:35

为什么不直接使用ItemsControl作为区域呢?它垂直堆叠物品,并且Prism有内置的区域适配器。我不明白你为什么要用StackPanel来做布局以外的任何事情。

默认情况下,ItemsControl使用包含StackPanel的ItemsPanel,因此它等同于已经提供的答案,但没有不必要的代码。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4950464

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文