Призма: складывать элементы управления в регионе? - PullRequest
4 голосов
/ 10 февраля 2011

Моему приложению Prism необходимо вставить кнопки из нескольких модулей в область оболочки.Кнопки будут расположены вертикально, как кнопки навигации (Почта, Календарь и т. Д.) В Outlook 2010. Я использую пользовательские элементы управления в качестве кнопок, поэтому мне не нужно беспокоиться о шаблонах - моя проблема такая жеесли бы я вставлял простые радиокнопки.

Как настроить область так, чтобы кнопки выглядели сложенными вертикально?Спасибо за вашу помощь.

Ответы [ 6 ]

6 голосов
/ 21 февраля 2011

Из комментария NVenhola в области «Заполнить мою призму», статья , есть простое, адаптируемое решение:

<ItemsControl cal:RegionManager.RegionName="XXRegionNameXX">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>
6 голосов
/ 10 февраля 2011

Решение Мэтта объясняется в «Руководстве для разработчиков по Microsoft Prism» (V4) на стр. 189-191.

Для разработчиков C #, исследующих эту проблему, приведен перевод адаптера Мэтта на C #:

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 - переопределение ConfigureRegionAdapterMappings () в C #, обновленное для Prism.4:

/// <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 голосов
/ 10 февраля 2011

StackPanel сразу же приходит на ум, когда думает о вертикальной укладке предметов.К сожалению, Prism не поддерживает StackPanel как регион из коробки.К счастью, вы можете создать RegionAdapter для решения этой проблемы.

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 в вашем загрузчике.Ссылка Джона Папа, из которой я изначально получил код.(В C #, если вы используете это) Заполните мою область призмы, пожалуйста

5 голосов
/ 10 февраля 2011

Почему бы просто не использовать ItemsControl в качестве региона? Он укладывает предметы вертикально, и Prism имеет встроенные адаптеры для этого региона. Я не понимаю, почему вы хотите использовать StackPanel для чего угодно, кроме макета.

ItemsControl по умолчанию использует ItemsPanel, которая содержит StackPanel, поэтому она эквивалентна уже предоставленным ответам, но без лишнего кода.

1 голос
/ 11 сентября 2011

Как насчет использования itemscontrol, который просто делает то, что вы хотите.По умолчанию ItemsControl будет использовать стековую панель для визуализации представлений модуля.

0 голосов
/ 24 ноября 2013

также будьте очень осторожны с экземпляром RegionAdapterMapping в Bootstrapper.cs: напишите это так:

protected override RegionAdapterMappings ConfigureRegionAdapterMappings()
{
    //this is the correct way
    RegionAdapterMappings regionAdapterMappings = base.ConfigureRegionAdapterMappings(); 
    regionAdapterMappings.RegisterMapping(typeof(StackPanel), Container.Resolve<StackPanelRegionAdapter>());
    return regionAdapterMappings;
 }

Мне потребовались часы, чтобы понять, что вы не можете написать:

//RegionAdapterMappings regionAdapterMappings = new RegionAdapterMappings(); 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...