I have a tab control in my WPF application and I'm trying to position the TabItem headers to the left as shown in this MSDN post using the below code (copied from the post):
<TabControl TabStripPlacement="Left" Margin="0, 0, 0, 10">
<TabItem Name="TabOne" Header="Tab One">
<TabItem.Content>
<TextBlock TextWrapping="WrapWithOverflow">
Tab One Here.
</TextBlock>
</TabItem.Content>
</TabItem>
<TabItem Name="TabTwo" Header="Tab Two">
<TabItem.Content>
<TextBlock TextWrapping="WrapWithOverflow">
Tab Two here.
</TextBlock>
</TabItem.Content>
</TabItem>
</TabControl>
According to the post this is what Im supposed to get:
But this is what I'm currently getting:
I've copied the exact same code from the post to my application and can't understand what has gone wrong.
Here is my full xaml:
<Window x:Class="OptionsWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TabStripPlacementSample" Height="200" Width="250" UseLayoutRounding="True">
<Grid>
<TabControl TabStripPlacement="Left" Margin="0,0,33,10">
<TabItem Name="TabOne" Header="Tab One">
<TabItem.Content>
<TextBlock TextWrapping="WrapWithOverflow">
Tab One Here.
</TextBlock>
</TabItem.Content>
</TabItem>
<TabItem Name="TabTwo" Header="Tab Two">
<TabItem.Content>
<TextBlock TextWrapping="WrapWithOverflow">
Tab Two here.
</TextBlock>
</TabItem.Content>
</TabItem>
</TabControl>
</Grid>
Related
I had the following code
<mah:MetroWindow x:Class="NeoTec.SprayMachine.WPF.MainWindow"
namespaces bla bla>
<Window.Resources>
<DataTemplate DataType="{x:Type viewModels:CompanyDatabaseViewViewModel}">
<controls:CompanyDatabaseViewControl/>
</DataTemplate>
<DataTemplate DataType="{x:Type viewModels:UserDatabaseViewViewModel}">
<controls:UserDatabaseViewControl/>
</DataTemplate>
<DataTemplate DataType="{x:Type viewModels:ParametersViewModel}">
<controls:ParamatersControl/>
</DataTemplate>
<DataTemplate DataType="{x:Type viewModels:SettingsViewModel}">
<controls:SettingsControl/>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition/>
</Grid.RowDefinitions>
<controls:UpperPanelControl HorizontalAlignment="Center"/>
<ContentControl Grid.Row="1" Content="{Binding ShownViewModel}"/>
</Grid>
</mah:MetroWindow>
Where UpperPanelControl is a control with buttons that changes ShownViewModel in MainViewModel. For design purposes I decided to change this all to TabControl (there was a requirement from customer to have buttons):
<mah:MetroWindow x:Class="NeoTec.SprayMachine.WPF.MainWindow"
namespaces bla bla>
<TabControl>
<TabItem Header="Company Database">
<controls:CompanyDatabaseViewControl DataContext="{Binding CompanyDatabaseViewModel}"/>
</TabItem>
<TabItem Header="User Database">
<controls:UserDatabaseViewControl DataContext="{Binding UserDatabaseViewModel}"/>
</TabItem>
<TabItem Header="Parameters" IsSelected="{Binding ParametersTabSelected}">
<controls:ParamatersControl DataContext="{Binding ParametersViewModel}"/>
</TabItem>
<TabItem Header="Settings">
<controls:SettingsControl DataContext="{Binding SettingsViewModel}"/>
</TabItem>
<TabItem Header="Info">
<controls:InfoControl/>
</TabItem>
</TabControl>
</mah:MetroWindow>
It looks nicer, but the problem is when I switch tab the data in the tab is not updated. Are there any chance to get this working with TabControl with updating bindings, when tab is changed?
Each TabItem has an IsSelected property. You can bind that in your View Model and take the appropriate action.
<TabItem Header="Company Database" IsSelected="{Binding CompanyDataBaseTabIsSelected}">
<controls:CompanyDatabaseViewControl DataContext="{Binding CompanyDatabaseViewModel}"/>
</TabItem>
private bool _companyDatabaseTabIsSelected;
public bool CompanyDatabaseTabIsSelected
{
get { return _companyDatabaseTabIsSelected; }
set
{
_companyDatabaseTabIsSelected = value;
_companyDatabaseViewModel.Refresh();
}
}
I have the following TabControl with 2 default tabitems.
<TabControl>
<TabControl.ItemTemplate>
<DataTemplate>
<ScrollViewer VerticalScrollBarVisibility="Auto" Height="300" Content="{Binding}"/>
</DataTemplate>
</TabControl.ItemTemplate>
<TabItem Header="Conexión"><local:ConnectionSettings/></TabItem>
<TabItem Header="Cuestionario"><local:QuestionEditor/></TabItem>
</TabControl>
The current xaml doesn't apply the ItemTemplate, for that to happen each tabitem would need to be "naked", like this:
<TabControl>
<TabControl.ItemTemplate>
<DataTemplate>
<ScrollViewer VerticalScrollBarVisibility="Auto" Height="300" Content="{Binding}"/>
</DataTemplate>
</TabControl.ItemTemplate>
<!-- The ItemTemplate is only applied if tabitems are not wrapped in TabItem tags -->
<local:ConnectionSettings/>
<local:QuestionEditor/>
</TabControl>
But if I do that, then I can't specify the header.
I would like for every TabItem to be wrapped in a ScrollViewer (as specified in the ItemTemplate), but at the same be able to specify the header.
Is there a way to apply the ItemTemplate to <TabItem Header="MyHeader"/> tags?
ItemTemplate is the template to format the ItemsSource the headers on top of your tab control. ContentTemplate is the template to format the content of the tabs. To wrap your defined content to the scroll viewer, just make use of a new content control inside your template. Here is a minimal sample:
<TabControl>
<TabControl.ContentTemplate>
<DataTemplate>
<ScrollViewer>
<ContentControl Content="{TemplateBinding Property=ContentControl.Content}"/>
</ScrollViewer>
</DataTemplate>
</TabControl.ContentTemplate>
<TabItem>
<Button Content="Button1"/>
</TabItem>
<TabItem>
<Button Content="Button2"/>
</TabItem>
</TabControl>
What I'm trying to achieve here is to change the white of the header text. (Dialogs, Mahapps, Palette) to something else and also the green below Dialogs. I tried changing the white to black using foreground property but that didn't do anything.
<dragablz:TabablzControl FixedHeaderCount="3" >
<TabItem Foreground="Black" Header="DIALOGS">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">Hello World</TextBlock>
</TabItem>
<TabItem Header="MATERIAL">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">Material Design</TextBlock>
</TabItem>
<TabItem Header="PALETTE">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">Looks Quite Nice</TextBlock>
</TabItem>
</dragablz:TabablzControl>
You can add your "own" TextBlock element to the Header of the TabItem, and there set the Foreground brush (and override any styles that might otherwise affect it) like this:
<TabItem>
<TabItem.Header>
<TextBlock Text="DIALOGS" Foreground="Black" />
</TabItem.Header>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">Hello World</TextBlock>
</TabItem>
Going off this sample from the MSDN under TabControl:
<TabControl>
<TabItem>
<TabItem.Header>
<StackPanel Orientation="Horizontal">
<Ellipse Width="10" Height="10" Fill="DarkGray"/>
<TextBlock>Tab 1</TextBlock>
</StackPanel>
</TabItem.Header>
<StackPanel>
<TextBlock>Enter some text</TextBlock>
<TextBox Name="textBox1" Width="50"/>
</StackPanel>
</TabItem>
<TabItem Header="Tab 2">
<!--Bind TextBlock.Text to the TextBox on the first
TabItem.-->
<TextBlock Text="{Binding ElementName=textBox1, Path=Text}"/>
</TabItem>
</TabControl>
How do you access the stackpanel (and it's children) that is inside the <TabItem.Header> tag from C# code behind? When I try to use .Header intellisense treats it as if the header was defined the way the 2nd tab above is.
I agree with HighCore. You should be using databinding instead of trying to manipulate the UI elements directly. In the off chance that you want to stick with your current plan, here's how:
<TabControl>
<TabItem>
<TabItem.Header>
<StackPanel Name="tab1StackPanel" Orientation="Horizontal">
...
</StackPanel>
</TabItem.Header>
</TabItem>
<TabItem Header="Tab 2">
...
</TabItem>
</TabControl>
Now, from code behind you can reference tab1StackPanel directly, as defining a Name exposes it to codebehind WPF (as long as it's not inside a template).
You could also use the VisualTreeHelper to find visual children of the first tab...
BUT... once again, you should probably be using databinding, so I'd make sure you're following a good pattern before going too much further.
I don't know if it works but you can give it a try:
(tabItem.Header as ContentControl).FindName("NAME_OF_TEXTBLOCK");
I am using MVVM. I have TabItems with headers mytabItem, mytabItem2. How to bind a function so that I can open a new Window on double click on Header of tab.
<Grid Grid.Column="1" Grid.Row="3" Grid.ColumnSpan="3" Margin="79,0,0,0">
<TabControl Name="myTabControl">
<TabItem Name ="mytabItem" Header="Double cllick me">
<TextBlock Text="Hello world!"/>
</TabItem>
<TabItem Name ="mytabItem1" Header="cllick me" MouseDoubleClick="">
<TextBlock Text="Hello Water!"/>
</TabItem>
</TabControl>
</Grid>