在TabControl中显示多个控件类型

本文关键字:控件 类型 显示 TabControl | 更新日期: 2023-09-27 18:29:35

全部,我创建了一个TabControl来保存包含单个控件类型的TabitemMainWindow.xaml的标记为,如下所示

...
<TabControl x:Name="tabControl" 
            ItemsSource="{Binding Path=Workspaces}" 
            SelectedIndex="{Binding SelectedIndex}"
            IsSynchronizedWithCurrentItem="true" 
            HorizontalContentAlignment="Stretch" 
            VerticalContentAlignment="Stretch" 
            HorizontalAlignment="Stretch" 
            VerticalAlignment="Stretch" 
            TabStripPlacement="Top" 
            Margin="5,0,5,0">
    <TabControl.ItemContainerStyle>
        <Style TargetType="TabItem">
            <Setter Property="Header" Value="{Binding Path=DisplayName}"/>
            <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
            <Setter Property="VerticalContentAlignment" Value="Stretch"/>
        </Style>
    </TabControl.ItemContainerStyle>
    <TabControl.ContentTemplate>
        <DataTemplate>
            <Views:ResourceControl DataContext="{Binding}" 
                                   HorizontalAlignment="Stretch" 
                                   VerticalAlignment="Stretch"/>
        </DataTemplate>
    </TabControl.ContentTemplate>
</TabControl>
...

这对我的Views:ResourceControl非常有效,但我现在想扩展TabControl中显示的控件类型。为此,我创建了链接到从基本"WorkspaceViewModel"继承的视图模型的控件,并创建了以下资源文件

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:ViewModels="clr-namespace:ResourceStudio.ViewModels"
                    xmlns:Views="clr-namespace:ResourceStudio.Views">
    <DataTemplate DataType="{x:Type ViewModels:ResourceDataViewModel}">
        <Views:ResourceControl />
    </DataTemplate>
    <DataTemplate DataType="{x:Type ViewModels:StartPageViewModel}">
        <Views:StartPageControl/>
    </DataTemplate>
    <DataTemplate x:Key="WorkspacesTemplate">
        <TabControl x:Name="tabControl" 
                    IsSynchronizedWithCurrentItem="true" 
                    ItemsSource="{Binding}" 
                    SelectedIndex="{Binding SelectedIndex}"
                    HorizontalContentAlignment="Stretch" 
                    VerticalContentAlignment="Stretch" 
                    HorizontalAlignment="Stretch" 
                    VerticalAlignment="Stretch" 
                    TabStripPlacement="Top" 
                    Margin="5,0,5,0">
            <TabControl.ItemContainerStyle>
                <Style TargetType="TabItem">
                    <Setter Property="Header" Value="{Binding Path=DisplayName}"/>
                    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                    <Setter Property="VerticalContentAlignment" Value="Stretch"/>
                </Style>
            </TabControl.ItemContainerStyle>
        </TabControl>
    </DataTemplate>
</ResourceDictionary>

现在在MainWindow.xaml中我有

<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="MainWindowResources.xaml" />
        </ResourceDictionary.MergedDictionaries>
        <Style x:Key="DescriptionHeaderStyle" TargetType="Label">
            <Setter Property="FontSize" Value="22" />
            <Setter Property="HorizontalAlignment" Value="Center" />
        </Style>
    </ResourceDictionary>
</Window.Resources>
...
<ContentControl
    Content="{Binding Path=Workspaces}" 
    ContentTemplate="{StaticResource WorkspacesTemplate}">
</ContentControl>

绑定似乎注册了我想要显示的不同视图,因为选项卡显示了相关的标题。但是,实际控件直到我加载另一个表单才显示。在切换/加载选项卡项时,SelectedIndex似乎没有绑定,视图也没有更新。

如何更改WorkspaceTemplate以解决此问题

谢谢你抽出时间。


编辑。请求有关MainViewModel的信息。

public class MainWindowViewModel : WorkspaceViewModel 
{
    private readonly IDialogService dialogService;
    private WorkspaceViewModel selectedWorkspace;
    private ObservableCollection<WorkspaceViewModel> workspaces;
    private Dictionary<string, string> resourceDictionary;
    public MainWindowViewModel()
    {
        base.DisplayName = "SomeStringName";
        resourceDictionary = new Dictionary<string, string>();
        dialogService = ServiceLocator.Resolve<IDialogService>();
        Contract.Requires(dialogService != null);
    }
    ...
    private void OnWorkspacesChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.NewItems != null && e.NewItems.Count != 0)
            foreach (WorkspaceViewModel workspace in e.NewItems)
                workspace.RequestClose += this.OnWorkspaceRequestClose;
        if (e.OldItems != null && e.OldItems.Count != 0)
            foreach (WorkspaceViewModel workspace in e.OldItems)
                workspace.RequestClose -= this.OnWorkspaceRequestClose;
    }
    private void OnWorkspaceRequestClose(object sender, EventArgs e)
    {
        WorkspaceViewModel workspace = sender as WorkspaceViewModel;
        workspace.Dispose();
        int currentIndex = Workspaces.IndexOf(workspace);
        this.Workspaces.Remove(workspace);
        if (this.Workspaces.Count > 0)
            this.SetActiveWorkspace(Workspaces[currentIndex - 1]);
    }
    private void SetActiveWorkspace(WorkspaceViewModel workspace)
    {
        Debug.Assert(this.Workspaces.Contains(workspace));
        ICollectionView collectionView = CollectionViewSource.GetDefaultView(this.Workspaces);
        if (collectionView != null)
            collectionView.MoveCurrentTo(workspace);
    }
    public WorkspaceViewModel SelectedWorkspace
    {
        get { return selectedWorkspace; }
        set { selectedWorkspace = value; }
    }   
    private int selectedIndex = 0;
    public int SelectedIndex
    {
        get { return selectedIndex; }
        set
        {
            if (selectedIndex == value)
                return;
            selectedIndex = value;
            OnPropertyChanged("SelectedIndex");
        }
    }
    /// <summary>
    /// Returns the collection of available workspaces to display.
    /// A 'workspace' is a ViewModel that can request to be closed.
    /// </summary>
    public ObservableCollection<WorkspaceViewModel> Workspaces
    {
        get
        {
            if (workspaces == null)
            {
                workspaces = new ObservableCollection<WorkspaceViewModel>();
                workspaces.CollectionChanged += this.OnWorkspacesChanged;
            }
            return workspaces;
        }
    }
    ...
}

在TabControl中显示多个控件类型

我在使用您的代码时遇到了类似的情况。不确定是不是同一个。当我的应用程序加载时,它显示了第一个选项卡(第0个)及其正确的内容。选择时,第二个内容区域变为空白,没有发生任何事情。

我将Content="{Binding Path=Workspaces}"移动到TabControl,即

Content="{Binding}"

<TabControl ItemsSource="{Binding Workspaces}"/> 

它开始显示选项卡的内容。我使用了更多精简版的虚拟机。只是CCD_ 12的集合。