【问题标题】:How to manage content for multiple TabControlItems in a Prism application?如何在 Prism 应用程序中管理多个 TabControlItems 的内容?
【发布时间】:2018-08-22 10:20:07
【问题描述】:

Prism 6. 和 MVVM 设计模式的帮助下,我正在开发一个使用 C# 的新 WPF 应用程序。

我有一个带有TopRightCenter 区域的主窗口。在顶部区域我有一个工具栏,当用户单击“显示消息”按钮时,我会在中心区域显示一个名为“消息”的视图。我可以使用RegionManager.RequestNavigate 方法来显示运行正常的“消息”视图。

但是,我的“消息”视图有多个标签。当用户单击 TabControlItems 时,我希望能够在选项卡内容中显示不同的视图。

这是我的Message 视图的样子。这里的想法是有一个ViewModels的集合,并根据集合显示标签。

<TabControl ItemsSource="{Binding ViewModelCollection}"
            Background="Transparent">

    <i:Interaction.Triggers>
        <i:EventTrigger EventName="SelectionChanged">
            <prism:InvokeCommandAction Command="{Binding TabSelectionChangedCommand}"
                                       CommandParameter="{Binding ViewName}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>

    <TabControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding TabTitle}" />
        </DataTemplate>
    </TabControl.ItemTemplate>

    <TabControl.ContentTemplate>
        <DataTemplate>
            <ContentControl prism:RegionManager.RegionName="{x:Static foundation:RegionNames.TabContentRegionName}" />
        </DataTemplate>
    </TabControl.ContentTemplate>
</TabControl>

然后在我的MessageViewModel 我有以下代码

public class MessageViewModel : BindableBase
{
    public ObservableCollection<TabBasedNavigationAwareViewModel> ViewModelCollection { get; set; }
    public DelegateCommand<string> ChangeTabContent { get; set; }

    public MessageViewModel(IUnitOfWork unitOfWork, IPassportManager passportManager, ICoreRegionManager regionManager, IUnityContainer container)
    : base(unitOfWork, passportManager, regionManager)
    {
        ViewModelCollection = new ObservableCollection<TabBasedNavigationAwareViewModel>();

        ViewModelCollection.Add(container.Resolve<FirstViewModel>());
        ViewModelCollection.Add(container.Resolve<SecondViewModel>());

        ChangeTabContent = new DelegateCommand<string>(HandleChangeContent, CanChangeContent);
    }

    protected bool CanChangeContent(string viewName)
    {
        return true;
    }

    protected void HandleChangeContent(string viewName)
    {
        IRegion region = RegionManager.Regions[RegionNames.TabContentRegionName];

        region.RequestNavigate(new Uri("Modules.Messages.Views." + viewName, UriKind.Relative));
    }

    public override void OnNavigatedTo(NavigationContext navigationContext)
    {
        ChangeTabContent.Execute("FirstView");
    }
}

问题是应用程序启动时出现错误

区域管理器不包含 TabContent 区域。

我清楚地理解错误及其发生的原因。但不确定如何解决。在主区域内使用选项卡控件时,区域可能是错误的做法。我还尝试从MessageViewModel构造函数RegionManager.RegisterViewWithRegion(RegionNames.TabContentRegionName, typeof(MessageView));调用以下代码

当用户单击选项卡时,管理/显示正确视图的正确方法是什么?

请注意,我使用的是Fody.PropertyChanged 包,因此它会在属性更改时自动通知。

更新

我试图从视图中删除区域,现在我得到选项卡并且内容屏幕显示FirstViewModel 全名而不是相应的视图。 这是我没有区域的代码

public class MessageViewModel : BindableBase
{
    public ObservableCollection<TabBasedNavigationAwareViewModel> ViewModelCollection { get; set; }

    public MessageViewModel(IUnitOfWork unitOfWork, IPassportManager passportManager, ICoreRegionManager regionManager, IUnityContainer container)
    : base(unitOfWork, passportManager, regionManager)
    {
        ViewModelCollection = new ObservableCollection<TabBasedNavigationAwareViewModel>();

        ViewModelCollection.Add(container.Resolve<FirstViewModel>());
        ViewModelCollection.Add(container.Resolve<SecondViewModel>());
    }
}

这里是风景

<TabControl ItemsSource="{Binding ViewModelCollection}"
             Background="Transparent">

    <TabControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding TabTitle}" />
        </DataTemplate>
    </TabControl.ItemTemplate>

</TabControl>

【问题讨论】:

  • TabContent 区域有什么用?你导航到某个地方吗?我想,你可以删除它。
  • 但是当一个标签被点击时如何改变内容呢?
  • 这是TabControl 的工作,不是吗?你给它一个视图模型的集合,它会显示一个选项卡的集合。
  • @Haukinger yes 在普通的TabControl 中会为我处理内容切换。但是如何将内容放在哪里?我从 ViewContent 中删除了区域,但这给了我一个空白屏幕。我用更新的代码更新了我的问题

标签: c# wpf wpf-controls prism prism-6


【解决方案1】:

还为您的标签视图模型添加一些DataTemplates 到附近的资源字典中

<DataTemplate DataType="{x:Type FirstViewModel}">
    <TextBlock Text="{Binding SomeContent}"/>
</DataTemplate>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 2010-10-24
    • 1970-01-01
    相关资源
    最近更新 更多