2011-02-09 34 views
4

私のPrismアプリケーションは、複数のモジュールのボタンをシェル領域に挿入する必要があります。ボタンはOutlook 2010のナビゲーションボタン(メール、カレンダーなど)のように垂直に積み重ねられます。私はボタンとしてカスタムコントロールを使用していますので、テンプレートについて心配する必要はありません - 私の問題はプレーンなラジオボタンを挿入していたらプリズム:リージョンのコントロールを積み重ねる?

ボタンを縦に積み重ねて表示するには、どのように領域を設定しますか?ご協力いただきありがとうございます。

+0

はあなたを持っている:それはあなたカント書き込みを把握するために私に時間を要した

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

StackPanelを領域として使用しようとしましたか? – pdiddy

答えて

6

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オーバーライドにマッピングを追加する必要があります。

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 

編集:元々コードを取得したジョンパパリンクを見つけました。 (C#で使用している場合)Fill My Prism Region, Please

+0

受け入れられ、+1のコードです。ありがとうございました - 私はスタックパネルを考えましたが、それを動作させる方法を理解できませんでした。 –

+0

なぜItemsControlはありませんか? –

6

Mattのソリューションについては、「Microsoftプリズムの開発者ガイド」(V4)の189-191ページで説明しています。ここでは、この問題を調査、C#の開発者にとって

は、C#にMattのアダプタの翻訳です:

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(); 
     } 
    } 
} 

そしてブートストラップのために、ここではプリズム4用の更新C#でConfigureRegionAdapterMappings()のオーバーライドは、次のとおりです。

/// <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; 
} 
5

リージョンとしてItemsControlを使用するだけではどうですか。アイテムを垂直に積み重ね、Prismにはそのためのリージョンアダプタが組み込まれています。レイアウト以外の目的でStackPanelを使用する理由を理解できません。

ItemsControlはデフォルトでStackPanelを含むItemsPanelを使用するため、既に提供されている回答と同じですが、不要なコードはありません。

6

NVenholaのcomment in the Fill My Prism Region, Please articleから、簡単に、適応ソリューションがあります:ちょうどあなたが欲しいものをやってやっているのItemsControlを使用する方法について

<ItemsControl cal:RegionManager.RegionName="XXRegionNameXX"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <StackPanel/> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
</ItemsControl> 
1

どのように。デフォルトでは、ItemsControlはスタックパネルを使用してモジュールビューを表示します。また

0

Bootstrapper.csでインスタンスをRegionAdapterMappingについて非常に注意してください: このようにそれを書く:

//RegionAdapterMappings regionAdapterMappings = new RegionAdapterMappings(); 
関連する問題