Reputation: 91
I am adding 5 XAML views (i.e. UserControls) to the Tab Control WPF. The corresponding tab items for each UserControl
has rendered as expected. But I wonder how to set header for those tab items. Is there any way? Note: I dont want to add tab items directly to a TabControl
.
My UserControl:
public class TimeConsumingView : UserControl
{
public string Header
{
get { return (string)GetValue(HeaderProperty); }
set { SetValue(HeaderProperty, value); }
}
// Using a DependencyProperty as the backing store for Header.
// This enables animation, styling, binding, etc...
public static readonly DependencyProperty HeaderProperty =
DependencyProperty.Register(
"Header",
typeof(string),
typeof(TimeConsumingView),
new UIPropertyMetadata(
"",
new PropertyChangedCallback(OnHeaderChanged)));
}
My Shell view:
<TabControl x:Name="TabControl">
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Header}" x:Name="grid" />
</DataTemplate>
</TabControl.ItemTemplate>
<!--<local:GeneralView Header="General"/>-->
<local:TimeConsumingView Header="2006 - 2007"/>
<local:TimeConsumingView Header="2007 - 2008"/>
</TabControl>
In this case, the header not bound to the TextBlock
. When seen from Snoop, it seems the DataContext
cannot traverse after the ContentPresenter
of TabItem
Header.
Upvotes: 1
Views: 2156
Reputation: 132558
Why don't you want to wrap your items in a TabItem
?
WPF does that anyways when it renders, which I suspect is your problem because the Header is null by default, so the ItemTemplate
has a null
DataContext (You can verify this with Snoop)
<TabControl x:Name="TabControl">
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Header}" x:Name="grid" />
</DataTemplate>
</TabControl.ItemTemplate>
<!--<local:GeneralView Header="General"/>-->
<TabItem Header="2006 - 2007">
<local:TimeConsumingView Header="2006 - 2007"/>
</TabItem>
<TabItem Header="2007 - 2008">
<local:TimeConsumingView Header="2007 - 2008"/>
</TabItem>
</TabControl>
If you really insist on not using a TabItem wrapper (which WPF will insert by default), use a TabItem Style which will set the Header property
<Style TargetType="{x:Type TabItem}">
<Setter Property="Header" Value="{Binding Header}" />
</Style>
Upvotes: 2
Reputation: 26352
I handle this by having a String in my ViewModel that contains the name of the Tabitem. I then simply bind to that String using XAML Bindings.
<TabControl
ItemsSource="{Binding Workspaces}"
SelectedItem="{Binding CurrentPage, Mode=TwoWay}"
SelectedIndex="{Binding SelectedWorkspace, UpdateSourceTrigger=PropertyChanged}">
<TabControl.ItemTemplate>
<DataTemplate>
<DockPanel>
<TextBlock Text="{Binding Header}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</DockPanel>
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
Inside my ViewModel for the Tab I have a property called Header.
public String Header { get; set; }
public MyConstructor()
{
Header = "Name of Tab";
}
An alternative solution would be to override ToString().
public override string ToString()
{
return "Name of my Tab";
}
Upvotes: 1