我正在使用Prism和MEF,我想动态地将标签项添加到标签控件中,而不是违反 棱镜 - MVVM - MEF规则。 有人可以通过简单的步骤/示例向我展示如何做到这一点
答案 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添加。
当然,你必须先做一些事情。
您需要修改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}"/>
...
现在您可以在任何地方定义TabControl区域。请注意,它应该使用我们之前定义的样式。
<TabControl Regions:RegionManager.RegionName="MyRegion" ... />
现在您可以使用您的视图导航到该区域...当然,您必须将该视图的DataContext设置为某些具有字符串属性TabHeaderText的ViewModel ...
现在它应该工作:)当然我们正在讨论导航,所以你应该为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";
}
希望有所帮助