17

是否可以将 TabItem 放入单独的 XAML 并引用如下内容:

<TabControl>
     <local:MyTabItem/>
</TabControl>



In Separate XAML:
<UserControl x:Class="MyProject.MyTabItem"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <TabItem Header="MyTab">

    </TabItem>
</UserControl>

当然它不起作用,但我想知道我该怎么做?

4

4 回答 4

37

如果您想要做的只是让代码更易于管理,那么我建议在用户控件中定义每个选项卡的数据,但在主选项卡控件中仍然有 TabItem。

假设您的原始代码是这样的:

<TabControl>
    <TabItem Header="Tab 1">
        <Grid>
            <TextBlock Text="Tab Data" />
        </Grid>
    </TabItem>
</TabControl>

为了使代码更易于管理,您可以将选项卡内容分解为 UserControl,例如:

<UserControl x:Class="WpfApplication19.Tab1Data"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             >
    <Grid>
        <TextBlock Text="Tab Data" />
    </Grid>
</UserControl>

然后在 TabControl 中使用该用户控件,如下所示:

    <TabControl>
        <TabItem Header="Tab 1">
            <tabData:Tab1Data />
        </TabItem>
    </TabControl>

如果你真的想在你的用户控件中包含 TabItem,那么你可以通过首先创建一个用户控件,然后将用户控件的类型更改为 TabItem 类型(确保在 xaml 根节点和后面的代码)。

这将为您留下一个如下所示的选项卡控件:

    <TabControl>
        <tabData:TabItem1 />
        <tabData:TabItem2 />
        <tabData:TabItem3 />
    </TabControl>

每个 TabItem1 的“用户控件”都属于 TabItem 类型。这是一个例子:

<TabItem x:Class="WpfApplication19.TabItem1"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         Header="Tab 1"
         >
    <Grid>
        <TextBlock Text="Tab Data" />
    </Grid>
</TabItem>

正如我所提到的,一定要更改后面的代码,以便它扩展 TabItem 而不是用户控件:

public partial class TabItem1 : TabItem
{
    public TabItem1()
    {
        InitializeComponent();
    }
}
于 2009-10-19T20:25:57.573 回答
12

Tony Borres 之前的回答已经涵盖了最重要的方面。但进一步的评论要求从后面的代码访问。所以我将扩展 Tony 的例子来展示这个方面。这个答案显示了所需的命名空间。我也将它们添加到托尼的答案中。

为了使代码更易于管理,建议在用户控件中定义每个选项卡的数据,但在主选项卡控件中仍保留 TabItem。例如,此策略可用于解决 FxCop CA1505:在使用具有多个选项卡项的选项卡控件时“避免不可维护的代码”。

假设这是原始代码:

<Window x:Class="WpfApplication19.MainWindow" ...>
    <TabControl>
        <TabItem Header="Tab 1">
            <Grid>
                <TextBlock Text="Data on Tab 1" Name="txtData1" />
            </Grid>
        </TabItem>
        <TabItem Header="Tab 2">
            <Grid>
                <TextBlock Text="Data on Tab 2" Name="txtData2" />
            </Grid>
        </TabItem>
    </TabControl>
</Window>

为了使代码更易于管理,可以将选项卡内容移动到 UserControl 中,例如:

<UserControl x:Class="WpfApplication19.Tab1Data"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             Loaded="OnControlLoaded"
             >
    <Grid>
        <TextBlock Text="Data on Tab 1" Name="txtData1" />
    </Grid>
</UserControl>

然后可以像这样在 TabControl 中使用新的用户控件:

<Window x:Class="WpfApplication19.MainWindow"
        xmlns:tabData="clr-namespace:WpfApplication19" ...>
    <TabControl>
        <TabItem Header="Tab 1">
            <tabData:Tab1Data x:Name="ucTab1Data" />
        </TabItem>
        <TabItem Header="Tab 2">
            <Grid>
                <TextBlock Text="Data on Tab 2" Name="txtData2"/>
            </Grid>
        </TabItem>
    </TabControl>
</Window>

现在可以从主窗口访问用户控件的内部小部件,反之亦然。请注意用户控件名称前面的“x:”。

public partial class MainWindow : Window
{
    private void AccessWidgetWithinUserControl()
    {
        ucTab1Data.txtData1.Text = "New text on Tab 1";
    }
}

public partial class Tab1Data : UserControl
{
    private MainWindow mainWindow = null; // Reference to the MainWindow

    public Tab1Data()
    {
        InitializeComponent();
    }

    // get a reference to main windows when it is available.
    // The Loaded Event is set in the XAML code above.
    private void OnControlLoaded(object sender, RoutedEventArgs e)
    {
        mainWindow = Window.GetWindow(this) as MainWindow;
    }

    private void AccessMainWindowsWidget()
    {
        mainWindow.txtData2.Text = "New text on Tab 2 in the main window";
    }
}

即使嵌入在自己的用户控件中,显示的访问 txtData2 的代码也是相同的。

于 2011-04-05T16:18:52.053 回答
3

从表面上看,这听起来最好通过 TabItem 控件的样式和/或模板来解决,您可以将其存储在单独的资源文件中。您需要多少自定义实际的 TabItem 将决定您是否可以只使用样式或是否需要模板。

你可以做的是在一个单独的资源文件中为每个 TabItem 定义一个命名样式,就像这样,创建一个看起来像这样的 MyResources.xaml:

<ResourceDictionary>
    <Style x:Key="MyTabItem" TargetType="{x:Type TabItem}">
      <!-- 
           you can just use simple property setters to set up 
           the TabItem or set the Template property to replace
           entire tab look and feel
      -->
    </Style>
</ResourceDictionary>

然后在您的主 App.xaml 文件中合并到资源字典中:

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="MyResources.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

最后,在您的应用程序中,您只需执行以下操作即可利用这些样式:

<TabItem Style="{DynamicResource MyTabItem}" />
于 2009-10-19T18:45:56.350 回答
1

我想你想要的是让 TabItem Content 单独声明。由于 TabItem 是 ContentControl,因此您可以将 UserControl 作为其内容。

<TabControl>
   <TabItem> 
       <local:YourTabContent1/>
   </TabItem>
   <TabItem> 
       <local:YourTabContent2/>
   </TabItem>
</TabControl>

在单独的 XAML 中:

<UserControl x:Class="MyProject.YourTabContent1"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <......blah blah.../>
</UserControl>

在另一个 XAML 中,您可以拥有内容 2

<UserControl x:Class="MyProject.YourTabContent2"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
   <......blah blah.../>
</UserControl>
于 2009-10-20T06:25:57.217 回答