tags:

views:

722

answers:

3

Is it possible to put a TabItem into a separate XAML and reference something like this:

<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"&gt;
    <TabItem Header="MyTab">

    </TabItem>
</UserControl>

Of course it doesn't work, but I am wondering how can I do this?

+1  A: 

On the surface this sounds like it would be best solved by a a style and/or template for the TabItem control which you can store in a separate resource file. How much you need to customize the actual TabItem will determine if you can just use a style or if you need a template.

What you can do is define a named Style for each TabItem in a separate resource file like so, create a MyResources.xaml that looks something like this:

<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>

Then in your main App.xaml file you merge in the resource dictionary:

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

Finally in your application you would leverage these Styles by simply doing:

<TabItem Style="{DynamicResource MyTabItem}" />
Drew Marsh
Sorry, I should have elaborated more. I am not going after reuse, but making my code more manageable. Right now I have all of my XAML in my main window. The bulkier items are contained in a TabControl. Breaking out the TabItems which contain several controls, would make it alot easier to deal with. I am just a beginner, so I an unsure what is the best approach. I will look into creating a template for the TabItem.
John Sheares
Ok, then I still think the style/template approach I've suggested is a good solution for this. I will elaborate in my answer.
Drew Marsh
+2  A: 

If what you want to do is simply make the code more manageable then I would recommend defining each tab's data in a user control, but still have the TabItem in the main tab control.

Let's assume that your original code was this:

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

To make the code more manageable you could break the tab contents into a UserControl such as:

<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>

And then use that user control in your TabControl like this:

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

If you really want to include the TabItem in your user control then you can do that by first creating a user control, and then change the type of the user control to the type TabItem (make sure you change this in both the xaml root node and the code behind).

This would leave you with a tab control that looks like this:

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

And each TabItem1 'User Control' would be of type TabItem. Here is an example:

<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>

And as I mentioned, be sure to change the code behind so that it extends TabItem instead of user control:

public partial class TabItem1 : TabItem
{
    public TabItem1()
    {
        InitializeComponent();
    }
}
Tony Borres
Thank you so much. It works perfectly as you shown in your answer!
John Sheares
A: 

I think what you wanted is to get TabItem Content declare separately. Since TabItem is a ContentControl you can present a UserControl as its content.

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

In Separate XAML:

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

In another XAML you can have content 2

<UserControl x:Class="MyProject.YourTabContent2"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
   <......blah blah.../>
</UserControl>
Jobi Joy
This works too. One thing that I noticed is that I have to redefine my resources again inside the tab content XAML because the ones that are defined for the window are not available. Also, how do I get a control that's in one of the tabs from the window code-behind that contains the TabControl? Do I use FindName()?
John Sheares