2

我将 Prism 与 MEF 一起使用,并且我想动态地将选项卡项添加到选项卡控件而不会违反 Prism - MVVM - MEF 规则。有人可以通过简单的步骤/示例告诉我如何做到这一点

4

3 回答 3

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";
}

希望有帮助

于 2013-01-20T16:44:26.757 回答
1

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

您可以拥有 TabControl区域...因此您可以通过某些视图简单地导航到该区域:) ...会发生什么?当您使用某些视图导航到 TabControl 区域时...该视图将添加为新的 TabItem。

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

  1. 您需要修改 TabControl 样式。你只需要告诉 TabControl 它在哪里可以找到 Tab 项的 Header。您当然可以将其添加到应用程序的资源中。

    因此,您需要 TabItemStyle... 在其中指定标题文本的位置...类似这样的...

        <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 ...

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

于 2013-01-20T16:36:08.930 回答
1

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; }
}
于 2013-01-16T11:55:24.427 回答