【问题标题】:Binding wrapped viewmodels to TabControl将包装好的视图模型绑定到 TabControl
【发布时间】:2018-02-22 08:17:04
【问题描述】:

我一直在尝试自动填充我的 TabControl,并且一直在查看这个 question,尽管它并没有完全涵盖封装的 VM,我无法弄清楚。

我的主视图模型

public class MainActionViewModel : ViewModelBase
{
    private readonly IDialogService dialogService;

    public ObservableCollection<ViewVM> Views { get; set; }

    public MainActionViewModel(IDialogService dialogService)
    {
        this.dialogService = dialogService;

        ObservableCollection<ViewVM> views = new ObservableCollection<ViewVM>
        {
            new ViewVM{ ViewDisplay="Inspections", ViewType = typeof(InspectionsView), ViewModelType = typeof(InspectionsViewModel)},
            new ViewVM{ ViewDisplay="Defects", ViewType = typeof(SecurityView), ViewModelType = typeof(SecurityViewModel)},
            new ViewVM{ ViewDisplay="Planned Works", ViewType = typeof(SecurityView), ViewModelType = typeof(SecurityViewModel)},
            new ViewVM{ ViewDisplay="Security", ViewType = typeof(SecurityView), ViewModelType = typeof(SecurityViewModel)}
        };
        Views = views;
        RaisePropertyChanged("Views");
    }
}

我的主视图

<Window x:Class="AptAction.MainAction"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="clr-namespace:AptAction"
      mc:Ignorable="d" 
      d:DesignHeight="500" d:DesignWidth="700"
      Title="AptAction">

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <TabControl Grid.Row="1"  ItemsSource="{Binding Views}" SelectedIndex="0">
            <TabControl.Resources>
                <DataTemplate DataType="{x:Type local:InspectionsViewModel}">
                    <local:InspectionsView/>
                </DataTemplate>
                <DataTemplate DataType="{x:Type local:SecurityViewModel}">
                    <local:SecurityView/>
                </DataTemplate>
            </TabControl.Resources>
            <TabControl.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding ViewDisplay}" />
                </DataTemplate>
            </TabControl.ItemTemplate>
        </TabControl>
        <TextBlock x:Name="UIMessage" Text="" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,0,8,0" Foreground="{StaticResource DarkBrightBrush}"/>
        <ContentControl x:Name="Holder" Grid.Row="2" />
    </Grid>
</Window>

TabItems 的内容是显示描述 LibsView.ViewVM,我需要更改/添加什么才能使其正确显示实际视图?

【问题讨论】:

  • 尝试删除&lt;TabControl.ItemTemplate&gt; &lt;DataTemplate&gt; &lt;TextBlock Text="{Binding ViewDisplay}" /&gt; &lt;/DataTemplate&gt; &lt;/TabControl.ItemTemplate&gt;。我认为它覆盖了您之前定义的根据模型类型显示视图的行为。
  • 你这样做是最困难的。您的视图模型具有不同的类型。将它们放入 ObservableCollection 并将其绑定到选项卡控件的 Items 属性。然后您可以使用视图模型的类型来选择正确的 DataTemplate。要执行您想要执行的操作,您必须创建一个自定义 DataTemplateSelector ,就像我在此处的回答 stackoverflow.com/questions/37328616/… 中一样,这是一个巨大的痛苦。不要打扰。

标签: c# wpf xaml mvvm tabcontrol


【解决方案1】:

您应该将InspectionsViewModelSecurityViewModel 的实例添加到您的ObservableCollection,而不是向其中添加ViewVM 对象。

创建InspectionsViewModelSecurityViewModel 都继承自的公共基类(或接口)并将集合的类型更改为ObservableCollection&lt;BaseType&gt;

public MainActionViewModel()
{
    ObservableCollection<BaseType> views = new ObservableCollection<BaseType>
            {
                new InspectionsViewModel(),
                new SecurityViewModel()
            };
    Views = views;
}

您也可以使用ObservableCollection&lt;object&gt;,因为您的两个类已经隐式继承自object

【讨论】:

    猜你喜欢
    • 2018-10-25
    • 2018-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多