如何以编程方式将选项卡项添加到棱镜中的选项卡控件

时间:2013-01-16 11:36:23

标签: wpf mvvm prism mef

我正在使用Prism和MEF,我想动态地将标签项添加到标签控件中,而不是违反 棱镜 - MVVM - MEF规则。 有人可以通过简单的步骤/示例向我展示如何做到这一点

3 个答案:

答案 0 :(得分:1)

TabControl可以像许多其他控件一样绑定到集合。这是我在聊天消息程序中使用的tabcontrol的示例。

<TabControl ItemsSource="{Binding Path=Rooms, Mode=OneWay}" SelectedItem="{Binding Path=SelectedRoom, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
      <TabControl.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Path=RoomName}" x:Name="Header" Tag="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}, Path=DataContext}"/>
            </DataTemplate>
      </TabControl.ItemTemplate>
      <TabControl.ContentTemplate>
            <DataTemplate>

                 //in here is where you put controls for what you want the tabs to look like.

            </DataTemplate>
      </TabControl.ContentTemplate>
 </TabControl>

因此,在此示例中,我有一个名为“Rooms”的自定义数据类型“ChatRoom”的集合,其中包含RoomName等属性。每当用户创建新房间时,它都会添加到Rooms集合中,并创建一个新的tabitem。所以在我的viewModel中:

private ObservableCollection<ChatRoom> _Rooms;

public MainWindowViewModel()
{
     this._Rooms = new ObservableCollection<ChatRoom>();
}

public ObservableCollection<ChatRoom> Rooms
{
   get { return this._Rooms; }
}

答案 1 :(得分:1)

首先,我并不是说我的方法是所有可行方法中最好的...但我只是想分享它,因为我认为这很酷:)

您可以使用TabControl 区域 ...这样您就可以通过某种视图导航到该区域:) ...会发生什么?当您使用某个视图导航到TabControl区域时...该视图将作为新的TabItem添加。

当然,你必须先做一些事情。

  1. 您需要修改TabControl样式。您只需要告诉TabControl它可以找到Tab项的标题。您可以将其添加到应用程序的资源中。

    所以你需要TabItemStyle ...你在哪里指定Header Text ...这样的东西......

        <Style x:Key="MyTabItemStyle" TargetType="{x:Type TabItem}">
        <Setter Property="Header" Value="{Binding Content.DataContext.TabHeaderText,     RelativeSource={RelativeSource Self}}"/>
        ...
    

    并在默认的TabControlStyle

    中使用它
    <Style TargetType="{x:Type TabControl}">
    <Setter Property="ItemContainerStyle" Value="{StaticResource MyTabItemStyle}"/>
    ...
    
  2. 现在您可以在任何地方定义TabControl区域。请注意,它应该使用我们之前定义的样式。

    <TabControl Regions:RegionManager.RegionName="MyRegion" ... />
    
  3. 现在您可以使用您的视图导航到该区域...当然,您必须将该视图的DataContext设置为某些具有字符串属性TabHeaderText的ViewModel ...

  4. 现在它应该工作:)当然我们正在讨论导航,所以你应该为ViewModels提供[RegionMemberLifetime(KeepAlive = true)]属性:)我希望有一天能帮助某人。

答案 2 :(得分:1)

您需要TabControl的区域适配器。我为Ribbon Control做了这个,所以你可以从中激发灵感:

public class RibbonRegionAdapter : RegionAdapterBase<Ribbon>
{
    public RibbonRegionAdapter(IRegionBehaviorFactory regionBehaviorFactory)
        : base(regionBehaviorFactory)
    {
    }

    protected override void Adapt(IRegion region, Ribbon regionTarget)
    {
        region.Views.CollectionChanged += (s, e) =>
        {
            if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
            {
                foreach (RibbonTabItem RibbonTab in e.NewItems)
                {
                    regionTarget.Tabs.Add(RibbonTab);
                }
            }

            if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
            {
                foreach (RibbonTabItem RibbonTab in e.OldItems)
                {
                    regionTarget.Tabs.Remove(RibbonTab);
                }
            }
        };
    }

    protected override IRegion CreateRegion()
    {
        return new AllActiveRegion();
    }
}
XAML中的

<Fluent:Ribbon prism:RegionManager.RegionName="{x:Static inf:RegionNames.RibbonRegion}"/>

添加您需要的标签:

IRegion RibbonRegion = _regionManager.Regions[RegionNames.RibbonRegion];
RibbonRegion.Add(YourTabItemView);

RegionNames只是我的基础设施项目中的一个类:

public class RegionNames
{
    public static string RibbonRegion = "RibbonRegion";
}

希望有所帮助