简体   繁体   English

使用棱镜库将视图注入 TabControl

[英]Inject view into TabControl using prism library

That's how I defined TabControl :这就是我定义TabControl的方式:

<TabControl ItemsSource="{Binding OpenedProjects, UpdateSourceTrigger=PropertyChanged}"
            SelectedItem="{Binding SelectedProject, Mode=OneWay}">
    <!-- headers -->
    <!-- header definition is unimportant for this question -->

    <!-- content -->
    <TabControl.ContentTemplate>
        <DataTemplate>
            <local:ProjectView />
        </DataTemplate>
    </TabControl.ContentTemplate>
</TabControl>

And these are the two methods I have defined in my Module class, that are used to register and use views:这些是我在模块类中定义的两个方法,用于注册和使用视图:

protected override void _initializeViews() {
    _container.RegisterType<MainMenuView>();
    _container.RegisterType<ProjectsView>();
    _container.RegisterType<ProjectView>();
    _container.RegisterType<ContentView>();
}

protected override void _initializeRegions() {
    IRegion menuRegion = _regionManager.Regions[RegionNames.MainMenuRegion];
    IRegion projectsRegion = _regionManager.Regions[RegionNames.ProjectsRegion];
    IRegion contentRegion = _regionManager.Regions[RegionNames.ContentRegion];

    menuRegion.Add(_container.Resolve<MainMenuView>());
    projectsRegion.Add(_container.Resolve<ProjectsView>());
    contentRegion.Add(_container.Resolve<ContentView>());
}

And the View constructor:和视图构造函数:

public ProjectView(ProjectsViewModel vm) {
    InitializeComponent();
    DataContext = vm;
}

What I want to achieve is to inject ProjectView into TabControl 's content area.我想要实现的是将ProjectView注入TabControl的内容区域。 Obviously, currently it doesn't work because of the ViewModel argument in the above constructor.显然,由于上述构造函数中的ViewModel参数,目前它不起作用。 How can I create this functionality, the PRISM way?我怎样才能创建这个功能,PRISM 方式?

EDIT:编辑:

I found this: How to inject views into TabControl using Prism?我发现了这个: How to inject views into TabControl using Prism? however if I do the same as the author of that question, I'm getting:但是,如果我与该问题的作者做同样的事情,我会得到:

System.InvalidOperationException: ItemsControl's ItemsSource property is not empty.

You TabControl didn't have a region so you can't inject something into your TabControl.您的 TabControl 没有区域,因此您无法向 TabControl 中注入内容。 Otherwise you only use simple MVVM to inject something into your view.否则你只能使用简单的 MVVM 将一些东西注入你的视图。

To use Prism to inject something in your TabControl.使用 Prism 在您的 TabControl 中注入一些东西。 You only need this line:你只需要这一行:

<TabControl prism:RegionManager.RegionName="TabRegion"/>

And then you can inject something very easy into your View.然后你可以很容易地在你的视图中注入一些东西。

_regionManager.RequestNavigate("TabRegion", new Uri("ProjectView", UriKind.Relative));

Before that you have to add the View to your Containier with:在此之前,您必须使用以下方法将视图添加到您的容器中:

UnityContainer.RegisterType<object, ProjectView>("ProjectView");

To add the Headertext you can easy changed the Style of the TabItem and bind the Header to the ViewModel from the ProjectView:要添加 Headertext,您可以轻松更改 TabItem 的样式并将 Header 绑定到 ProjectView 中的 ViewModel:

<UserControl.Resources>
    <Style TargetType="TabItem">
        <Setter Property="Header" Value="{Binding DataContext.Name}" />
    </Style>
</UserControl.Resources>

I hope that was the answer you looking for^^我希望那是你要找的答案^^

The answer from @ascholz help me to implement this. @ascholz 的回答帮助我实现了这一点。 Although the last step didn't work for me:尽管最后一步对我不起作用:

<UserControl.Resources>
    <Style TargetType="TabItem">
        <Setter Property="Header" Value="{Binding DataContext.Name}" />
    </Style>
</UserControl.Resources>

What i did instead was:我所做的是:

1 - Create a Tab Control with a prism region (Inside MainWindows in my case). 1 - 创建一个带有棱镜区域的选项卡控件(在我的例子中是在 MainWindows 内部)。

<TabControl prism:RegionManager.RegionName="TabRegion"/>

2 - Create a "user control" of type TabItem (NewTabView) that holds the tab views. 2 - 创建一个包含选项卡视图的 TabItem (NewTabView) 类型的“用户控件”。 Note that i'm binding the Header here.请注意,我在这里绑定了标题。 The idea here would be to add a region here as well inside the grid (for the content of the tab), or to make every control that needs to be inside the tab a child of TabItem.这里的想法是在此处以及网格内添加一个区域(用于选项卡的内容),或者使每个需要在选项卡内的控件成为 TabItem 的子控件。

<TabItem 
    x:Class="Client.WPF.Views.NewTab"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:prism="http://prismlibrary.com/"             
    prism:ViewModelLocator.AutoWireViewModel="True"
    Header="{Binding Title}">
    <Grid>
        <Button Content="{Binding RandomNumber}"/>
    </Grid>
</TabItem>
///The code behind should inherit from TabItem as well
public partial class NewTab : TabItem
///The viewmodel has a "Title" property
        private string _title = "New Tab";
        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }

4 - Finally, i navigate to the NewTab like this (MainWindowViewModel code) 4 - 最后,我像这样导航到 NewTab(MainWindowViewModel 代码)

        public DelegateCommand NewTab { get; }

        public MainWindowViewModel(IRegionManager regionManager, IEventAggregator eventAggregato)
        {
            this.regionManager = regionManager;
            this.eventAggregator = eventAggregator;

            NewTab = new DelegateCommand(NewTabAction);
        }

        private void NewTabAction()
        {
            regionManager.RequestNavigate("TabRegion", "NewTab");
        }

5 - As an added bonus, if you want to allow more than 1 instance of the tab, you can do something like this on the view model (NewTabViewModel). 5 - 作为一个额外的好处,如果你想允许超过 1 个选项卡实例,你可以在视图模型 (NewTabViewModel) 上做这样的事情。

///First add the IConfirmNavigationRequest interface
public class NewTabViewModel : BindableBase, IConfirmNavigationRequest
///...
///Then the implementation should look like this
        public void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback)
        {

            continuationCallback(true);///Will allow multiple instances (tabs) of this view
        }

        public void OnNavigatedTo(NavigationContext navigationContext)
        {

        }

        public bool IsNavigationTarget(NavigationContext navigationContext)
        {

            return false;
        }

        public void OnNavigatedFrom(NavigationContext navigationContext)
        {

        }

Or you could also add views directly to the region.或者您也可以直接向该区域添加视图。 Although you would need to resolve views using the IContainerProvider.尽管您需要使用 IContainerProvider 来解析视图。 Something like this:像这样:

var view = containerProvider.Resolve<NewTab>();
regionManager.Regions["TabRegion"].Add(view);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM