将TabControl绑定到基于属性的单独视图

时间:2017-05-31 15:57:16

标签: c# wpf xaml data-binding

背景

我正在尝试使用ItemSource的接口将制表符控件绑定到许多不同的视图。

我只用

成功完成了这项工作
<Controls:MetroAnimatedSingleRowTabControl x:Name="ModuleTabControl"
                                               ItemsSource="{Binding TabItems}">
        <Controls:MetroAnimatedSingleRowTabControl.Resources>
            <DataTemplate DataType="{x:Type ViewModels:MainPageViewModel}">
                <Views:MainPageView/>
            </DataTemplate>
            <DataTemplate DataType="{x:Type ViewModels:ALDViewModel}">
                <Views:ALDView/>
            </DataTemplate>
            <DataTemplate DataType="{x:Type ViewModels:PumpingViewModel}">
                <Views:PumpingView/>
            </DataTemplate>
            <DataTemplate DataType="{x:Type ViewModels:VerticalFlowPondViewModel}">
                <Views:VerticalFlowPondView/>
            </DataTemplate>
        </Controls:MetroAnimatedSingleRowTabControl.Resources>
        <Controls:MetroAnimatedSingleRowTabControl.ItemTemplate>
            <DataTemplate>
                <TextBlock
                    Text="{Binding Header}"/>
            </DataTemplate>
        </Controls:MetroAnimatedSingleRowTabControl.ItemTemplate>
    </Controls:MetroAnimatedSingleRowTabControl>

其中Controls:MetroAnimatedSingleRowTabControl就像一个普通的标签控件。

当我只绑定到ObservableCollection<ViewModelBase> TabItems的属性时,这个方法对我有用但是我现在感觉好像没有拿着ViewModel的集合,我最好有一个这样的界面,我会继承自

public interface ITabItem
{
    ViewModelBase ViewModel { get; set; }
}

并且那些继承的类将存储在

的集合中

ObservableCollection<ITabItem> TabItems

我设法通过更改{Binding Header}来显示标题 {Binding ViewModel.Header}这是有效的。

问题:

如何将DataType属性链接到我使用{x:Type ViewModels:ALDViewModel}的TabItems ViewModel属性?

提前感谢您的帮助

1 个答案:

答案 0 :(得分:0)

目前尚不清楚您将如何使用界面以及它与ViewModel类的关联方式。要么没有足够的信息,要么您可能无法正确使用接口。为什么要在界面中存储视图模型实例?这对我来说没有意义,因为你的视图模型应该实现这个接口,而不是存储在里面。

所以,基本上,如果你的ViewModel要实现提到的话    ITabItem,您的代码应该按原样运行,因为实际    TabItems集合中的类型将保持不变。让我来    演示。

说,你之前有这样的事情:

public ObservableCollection<ViewModelBase> TabItems { get; set; }

// add view model to collection
TabItems.Add(new ALDViewModel());

使用界面后,最终会:

// view model now implements interface
public class ALDViewModel : ViewModelBase, ITabItem

public ObservableCollection<ITabItem> TabItems { get; set; }
TabItems.Add(new ALDViewModel());

由于在XAML中定义的DataTempltes基本上告诉您的TabControl如何显示类型,并且您的类型(视图模型)保持不变,因此无需进行任何更改。

但是,如果某个其他类型将在其中实现接口和存储视图模型,并且您希望绑定到该视图模型......那么,正如我所提到的那样,这没有任何意义,并且不是您应该如何处理查看模型和界面。

我不确定你的场景,但是如果你想将一些关于tabcontrol的常见逻辑移到单独的地方,你可以创建TabViewModel类,其中存储了选项卡的所有通用逻辑。它可能看起来像这样:

 /// <summary>
/// Common class for all tab viewmodels
/// </summary>
public abstract class TabViewModel : ViewModelBase
{
    /// <summary>
    /// Tab name showed to the user
    /// </summary>
    private string tabName;

    /// <summary>
    /// Gets or sets the tab name
    /// </summary>
    public string TabName
    {
        get
        {
            return tabName;
        }
        set
        {
            tabName = value;
            OnPropertyChanged();
        }
    }

然后像这样使用它:

public class ALDViewModel: TabViewModel    

public ObservableCollection<TabViewModel> TabItems { get; set; }

TabViewModel aldTab = new ALDViewModel();
aldTab.TabName = "ALD";
TabItems.Add(aldTab);

然后,您的XAML代码应该保持不变,这可能是处理MVVM中的选项卡的最有效方法。