MVVM将视图绑定到TabControlItems-视图不显示 [英] MVVM Binding Views to TabControlItems - Views don't display

查看:50
本文介绍了MVVM将视图绑定到TabControlItems-视图不显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在MainView的 TabControlItems 中显示不同的视图.

I want to display different views in TabControlItems in my MainView.

为此,我创建了一个像这样的类:

To do this I've created a class like this :

public sealed class TabItem
{
    public string Header { get; set; }
    public ViewModelBase Content { get; set; }
}

我在ViewModel中的 List 中调用的

:

That I call in a Listin my ViewModel :

private ObservableCollection<TabItem> _views;
public ObservableCollection<TabItem> Views
{
    get { return _views; }
    set
    {
        _views = value;
        RaisePropertyChanged(() => Views);
    }
}

public IndexMainViewModel()
{
    Views = new ObservableCollection<TabItem>();
    Views.Add(new TabItem { Header = "Export", Content = new ExportViewModel() });
    Views.Add(new TabItem { Header = "Import", Content = new ImportViewModel() });  
}

编辑,然后显示在我的视图中:

EDIT And then display in my View :

<window xmlns:views="clr-namespace:EDICOT_Module_Import_Export_Articles.View"
xmlns:vm="clr-namespace:EDICOT_Module_Import_Export_Articles.ViewModel"
xmlns:model="clr-namespace:EDICOT_Module_Import_Export_Articles.Model.Classes"
DataContext="{Binding IndexMainVM, Source={StaticResource Locator}}">

   <TabControl ItemsSource="{Binding Views}">
    <TabControl.Resources>
        <DataTemplate DataType="{x:Type model:TabItem}">
            <DataTemplate.Resources>
                <DataTemplate DataType="{x:Type vm:ImportViewModel}">
                    <views:ImportView />
                </DataTemplate>
                <DataTemplate DataType="{x:Type vm:ExportViewModel}">
                    <views:ExportView />
                </DataTemplate>
            </DataTemplate.Resources>
            <ContentControl Content="{Binding Content}"/>
        </DataTemplate>
    </TabControl.Resources>

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

问题是它只显示标题,而不显示内容(视图),而是显示TabItem类的路径.

The problem is that it displays only the header but not the content (the view), it shows instead the path to the TabItem class.

要提供更多信息:我已将代码截断以仅保留主题所需的内容,并且使用了MVVM Light.

To give more infos : I've truncated the code to keep only what the topic needs and I use MVVM Light.

我真的不明白我想念的东西!谢谢您的帮助.

I really don't get what I miss here ! Thx for your help.

推荐答案

问题是每个选项卡都绑定到 TabItem 的实例.您具有用于 vm:ExportViewModel vm:ImportViewModel 的数据模板.您现在看到错误了吗?

The problem is that each tab is bound to an instance of TabItem. You have DataTemplates for vm:ExportViewModel and vm:ImportViewModel. Do you see your error now?

有很多解决方案.最简单的方法是将Header文本移动到基本视图模型中,然后将该Tab控件绑定到ViewModels的集合.

There are many solutions for this. Simplest is to move the Header text into the base view model and bind that Tab control to a collection of ViewModels.

另一种选择是为 TabItem 添加一个DataTemplate,在其中粘贴一个ContentControl,然后将那个绑定到视图模型.这是一些类似于xaml的伪代码来说明这个想法:

Another alternative would be to add a DataTemplate for TabItem, stick a ContentControl in it, and bind that to the view model. Here's some xaml-like pseudocode to illustrate this idea:

<DataTemplate DataType="{x:Type vm:TabItem}">
    <ContentControl Content={Binding Content}" />
</DataTemplate>

您可能必须将视图模型的模板移到ContentControl的资源中,但是我认为这不是必需的.您可能需要调整TabItem数据模板,以便它也可以填充选项卡窗口.

You may have to move the templates for your view models into the resources of the ContentControl, but I don't think that's necessary. You might need to tweak the TabItem data template so that it fills the tab window as well.

第三 个选项是实施自定义

A third option would be to implement a custom DataTemplateSelector and use that in your Tab control. In this selector, simply crack open your TabItem and look at the Content property for the type. You can browse the source code for the default DataTemplateSelector to find out how to get the correct template for the given type. This method gets your hands deep in the gore of WPF, which is an interesting trip. I've done it once, and I prefer to not do it again. Actually, for your needs, the trip won't be as bad as mine. The default selector doesn't do squat, so returning base.SelectTemplate is worthless. I dug around in the framework for an example of how it should be implemented.

public class TabItemDataTemplateSelector : DataTemplateSelector
{
    public override DataTemplate
        SelectTemplate(object item, DependencyObject container)
    {
        var viewModel = item as TabItem;
        if (item == null)
            return null;
        else
            item = viewModel.Content;

        FrameworkElement fe = null;
        if (container is ContentPresenter)
            fe = (container as ContentPresenter)
                    .TemplatedParent as FrameworkElement;
        else
            fe = container as FrameworkElement;

        var key = new DataTemplateKey(item.GetType());
        return fe.TryFindResource(key) as DataTemplate;
    }
}

将其实例添加到某处的资源中

add an instance of that to a Resource somewhere

<derp:TabItemDataTemplateSelector x:Key="tidts"/>

然后将其绑定到

这篇关于MVVM将视图绑定到TabControlItems-视图不显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆