我将 Prism 与 MEF 一起使用,并且我想动态地将选项卡项添加到选项卡控件而不会违反 Prism - MVVM - MEF 规则。有人可以通过简单的步骤/示例告诉我如何做到这一点
3 回答
您需要一个用于 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";
}
希望有帮助
首先,我并不是说我的方法是所有可能的方法中最好的……但我只是想分享它,因为我认为它很酷:)
您可以拥有 TabControl区域...因此您可以通过某些视图简单地导航到该区域:) ...会发生什么?当您使用某些视图导航到 TabControl 区域时...该视图将添加为新的 TabItem。
当然,有些事情你必须先做。
您需要修改 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}"/> ...
现在您可以在任何地方定义 TabControl 区域。请注意,它应该使用我们之前定义的样式。
<TabControl Regions:RegionManager.RegionName="MyRegion" ... />
好吧,现在您可以使用视图导航到该区域...当然,您必须将该视图的 DataContext 设置为具有字符串属性 TabHeaderText 的某个 ViewModel ...
现在它应该可以工作了 :) 当然我们在谈论导航,所以你应该为 ViewModels 提供[RegionMemberLifetime(KeepAlive = true)]
属性 :) 我希望有一天它对某人有所帮助。
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; }
}