2011-02-09 41 views
4

我的Prism應用程序需要將幾個模塊的按鈕插入Shell區域。該按鈕將垂直Outlook 2010中我使用的按鈕自定義控件堆疊,像導航按鈕(郵件,日曆,等等),所以我並不需要擔心模板 - 我的問題是一樣的如果我插入簡單的單選按鈕。棱鏡:堆疊控制在一個地區?

如何設置,使這些按鈕會出現垂直堆疊的區域?謝謝你的幫助。

+0

有你嘗試使用StackPanel作爲區域? – pdiddy 2011-02-09 21:28:16

回答

6

的StackPanel立即跳轉垂直堆疊物品的思維時,在腦海中。不幸的是棱鏡不支持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。謝謝 - 我想到一個堆棧面板,但無法弄清楚如何使其工作。 – 2011-02-09 22:01:22

6

馬特的解決方案在'開發人員指南微軟棱鏡'(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(); 
     } 
    } 
} 

而且對於引導程序,這裏是ConfigureRegionAdapterMappings()重寫在C#中,更新的棱鏡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; 
} 
5

爲什麼不直接使用ItemsControl作爲區域?它垂直堆疊物品,而棱鏡具有內置區域適配器。我不明白你爲什麼要使用StackPanel來進行佈局的任何操作。

一個ItemsControl默認使用包含一個StackPanel的ItemsPanel,所以它等同於已經提供的答案,但沒有不必要的代碼。

6

從NVenhola的comment in the Fill My Prism Region, Please article,有一個簡單的,適應性強的解決方案:

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

如何只使用ItemsControl的,這只是做着做着你想要什麼。默認情況下,ItemsControl將使用堆棧面板來渲染模塊視圖。

0

也非常小心在Bootstrapper.cs RegionAdapterMapping例如: 它這樣寫:

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