如何通过 XAML 在 WPF TabControl 中添加控件

How to add controls inside WPF TabControl via XAML

我有以下 XAML,一个 TabControl 绑定到 ObservableCollection 并创建我的标签就好了。

<Window x:Class="BA_Auditing.AuditWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="BizeAsset - Audit Results" Height="700" Width="1120" WindowStartupLocation="CenterScreen" WindowState="Maximized">
    <Grid>
        <TabControl Name="ModuleTabControl" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="5" ItemsSource="{Binding}" >
            <TabControl.ItemTemplate>
                <DataTemplate>
                    <TextBlock>                            
                        <TextBlock Text="{Binding DISPLAY_NAME}"/>
                    </TextBlock>
                </DataTemplate>
            </TabControl.ItemTemplate>

            <TabControl.ContentTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition />
                            <RowDefinition Height="Auto" />
                            <RowDefinition />
                        </Grid.RowDefinitions>
                        <Grid Grid.Row="0">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition />
                                <ColumnDefinition />
                            </Grid.ColumnDefinitions>
                            <TextBlock Grid.Column="0" Text="Search:" HorizontalAlignment="Right"/>
                            <TextBox x:Name="tbxSearch" Grid.Column="1"/>
                        </Grid>
                        <TextBlock Grid.Row="2" Text="Items Selected: 0 of 908" />
                    </Grid>
                </DataTemplate>
            </TabControl.ContentTemplate>
        </TabControl>
    </Grid>
</Window>

接下来我想用下一级控件填充每个选项卡区域,其中将包括 LabelTextBox、另一个 TabControlTextBlock .

我之前在 WinForms 中写过这个,现在看起来是这样的:

我需要添加什么 XAML 才能做到这一点?
那是因为我通过绑定动态设计它而不是字面上添加 TabItem

[编辑]
我试图将控件输入 TabControl.ContentTemplate,但是 TabItem 的正文中没有任何显示。

我认为如果您在 "WW - Wastewater" 选项卡上有 "clicked",您会看到正在生成的内容(搜索框等)- 这是因为默认情况下未选择该选项卡。

无论如何,这里有一些代码可以让您更接近您想要的东西 - 这只是为了让您开始,您需要添加其他管道代码(更改通知等)。

我不知道您打算在 "Services" 选项卡等中包含什么...所以不知道您是否可以用与 "Assets" 相同的方式处理它们.此外,您可能希望明确定义网格列的名称,而不是让它们自动生成 - 您可以在其他地方找到一些技术来做到这一点。

<Window x:Class="WpfApp38.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp38"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TabControl Name="ModuleTabControl" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="5" ItemsSource="{Binding}" SelectedIndex="0" >
            <TabControl.ItemTemplate>
                <DataTemplate>
                    <TextBlock>                            
                        <TextBlock Text="{Binding DISPLAY_NAME}"/>
                    </TextBlock>
                </DataTemplate>
            </TabControl.ItemTemplate>

            <TabControl.ContentTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="*" />
                            <RowDefinition Height="Auto"/>
                        </Grid.RowDefinitions>
                            <Grid Grid.Row="0">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition />
                                    <ColumnDefinition />
                                </Grid.ColumnDefinitions>
                                <TextBlock Grid.Column="0" Text="Search:" HorizontalAlignment="Right"/>
                                <TextBox x:Name="tbxSearch" Grid.Column="1"/>
                            </Grid>
                        <TabControl Grid.Row="1" ItemsSource="{Binding SubCategories}">
                            <TabControl.ItemTemplate>
                                <DataTemplate>
                                    <TextBlock Text="{Binding DISPLAY_NAME}"/>
                                </DataTemplate>
                            </TabControl.ItemTemplate>
                            <TabControl.ContentTemplate>
                                <ItemContainerTemplate>
                                    <DataGrid AutoGenerateColumns="True" ItemsSource="{Binding Assets}">
                                    </DataGrid>
                                </ItemContainerTemplate>
                            </TabControl.ContentTemplate>
                        </TabControl>
                        <TextBlock Grid.Row="2" Text="Items Selected: 0 of 908" />
                    </Grid>
                </DataTemplate>
            </TabControl.ContentTemplate>
        </TabControl>
    </Grid>
</Window>

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp38
{
    public class InfrastructureCateogry
    {
        public string DISPLAY_NAME { get; set; }

        public ObservableCollection<AssetCategory> SubCategories { get; set; }
    }

    public class AssetCategory
    {
        public string DISPLAY_NAME { get; set; }

        public ObservableCollection<AssetRecord> Assets { get; set; }
    }

    public class AssetRecord
    {
        public string AssetID { get; set; } // make it an int
        public string AssetType { get; set; }
        public string LastUpdateBy { get; set; } // make this a DateTime object
        public string LastUpdateDate { get; set; } // make this a DateTime object
    }

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private ObservableCollection<InfrastructureCateogry> infrastructurecategories = new ObservableCollection<InfrastructureCateogry>();

        public MainWindow()
        {
            InitializeComponent();

            var x = new InfrastructureCateogry()
            {
                DISPLAY_NAME = "AR - Roads and Bridges",
                SubCategories = new ObservableCollection<AssetCategory>
                {
                    new AssetCategory
                    {
                        DISPLAY_NAME = "Lines",
                        Assets = new ObservableCollection<AssetRecord>
                        {
                            new AssetRecord
                            {
                                AssetID = "20040927104600",
                                AssetType = "Gravity Main",
                                LastUpdateDate = "07/05/2015 17:01:55 PM"
                            },
                            new AssetRecord
                            {
                                AssetID = "20150507170116",
                                AssetType = "Relined",
                                LastUpdateDate = "07/05/2015 17:01:15 PM"
                            }
                        }
                    },
                    new AssetCategory
                    {
                        DISPLAY_NAME = "Points"
                    },
                    new AssetCategory
                    {
                        DISPLAY_NAME = "Plant/Components"
                    },
                    new AssetCategory
                    {
                        DISPLAY_NAME = "Services"
                    }
                }
            };

            infrastructurecategories.Add(x);

            var x2 = new InfrastructureCateogry();
            x2.DISPLAY_NAME = "WW - WasteWater";

            infrastructurecategories.Add(x2);

            this.DataContext = infrastructurecategories;
        }
    }
}