TabControl not working inside stackpanel - c#

So I have a TabControl that normally resides inside a TabItem. I would like to put that tab control inside a StackPanel so I can add some content above the TabControl. However, as soon as I put the TabControl inside a StackPanel the application stops working -- there is a memory leak somewhere and if I look at my process in Windows Task Manager it just keeps using more and more memory until it needs shut down. My .xaml file is pretty straightforward:
<TabControl Name="tabControlOuter" Margin="0,20,0,0" Background="#222222" >
<TabItem>...</TabItem>
<TabItem>...</TabItem>
<TabItem Header="Something" Name="something">
<TabControl Name="tabControlInner" Style="{StaticResource TabControlStyle1}"/>
</TabItem>
And my tab control style:
<Style x:Key="TabControlStyle1" TargetType="{x:Type TabControl}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="Padding" Value="4,4,4,4"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="Background" Value="#222222"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabControl}">
<Grid x:Name="ctlgrid" ClipToBounds="true" SnapsToDevicePixels="true" KeyboardNavigation.TabNavigation="Local">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ColumnDefinition0"/>
<ColumnDefinition x:Name="ColumnDefinition1" Width="0"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition x:Name="RowDefinition0" Height="Auto"/>
<RowDefinition x:Name="RowDefinition1" Height="*"/>
</Grid.RowDefinitions>
<Grid Panel.ZIndex="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<WrapPanel x:Name="HeaderPanel" Grid.Column="0" IsItemsHost="true" Background="#666666" Grid.Row="0" KeyboardNavigation.TabIndex="1" Panel.ZIndex="1"/>
<DockPanel Width="300" x:Name="SearchDock" Background="#666666" Grid.Column="1" Height="65">
<Border BorderBrush="White" BorderThickness="1,0,1,0" HorizontalAlignment="Right" Margin="0,0,10,0"></Border>
<Label x:Name="searchStat" Height="30" DockPanel.Dock="Bottom" Foreground="White"></Label>
<TextBox x:Name="Search" Margin="0,0,10,0" Width="150" Height="30" DockPanel.Dock="Left" />
<Button ToolTip="Search" Width="35" Height="30" Padding="5,5,5,2" Margin="10,0,-30,0" Click="search_logs" DockPanel.Dock="Left" >
<Image Source="/Images/mglass.png" />
</Button>
<Button ToolTip="Next Search Result" Margin="0,0,20,0" Width="30" Height="30" Content="Next" Click="next_result" DockPanel.Dock="Right">
</Button>
<Button ToolTip="Previous Search Result" Margin="30,0,0,0" Width="30" Height="30" Content="Prev" Click="prev_result" DockPanel.Dock="Right">
</Button>
</DockPanel>
</Grid>
<Border x:Name="ContentPanel" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.Column="0" KeyboardNavigation.DirectionalNavigation="Contained" Grid.Row="1" KeyboardNavigation.TabIndex="2" KeyboardNavigation.TabNavigation="Local">
<ContentPresenter x:Name="PART_SelectedContentHost" ContentSource="SelectedContent" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="TabStripPlacement" Value="Left">
<Setter Property="Grid.Row" TargetName="HeaderPanel" Value="0"/>
<Setter Property="Grid.Row" TargetName="ContentPanel" Value="0"/>
<Setter Property="Grid.Column" TargetName="HeaderPanel" Value="0"/>
<Setter Property="Grid.Column" TargetName="ContentPanel" Value="1"/>
<Setter Property="Width" TargetName="ColumnDefinition0" Value="Auto"/>
<Setter Property="Width" TargetName="ColumnDefinition1" Value="*"/>
<Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
<Setter Property="Height" TargetName="RowDefinition1" Value="0"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Now the problem is if I throw a StackPanel around my inner tab control things go south fast
<TabItem Header="Something" Name="something">
<StackPanel>
<TabControl Name="tabControlInner" Style="{StaticResource TabControlStyle1}"/>
<StackPanel>
</TabItem>
I`m adding tab items to my tab control programatically as such below:
TabControl itemsTab = (TabControl)this.FindName("tabControlInner");
itemsTab.Items.Clear();
TabItem setThistab = (TabItem)this.FindName("something");
setThistab.IsSelected = true;
foreach (CustomItem ale in my_collection)
{
TabItem newTab = new TabItem();
FrameDisplayTab ftab1 = new FrameDisplayTab();
ftab1.MyDatagrid.ItemsSource = ale.logentries;
newTab.Content = ftab1;
newTab.Header = ale.name;
itemsTab.Items.Add(newTab); <-- this is where I get into trouble from the stack pane. Everything works fine if my inner tab control is not in a stack panel or if I omit this line
}
Can someone see what is going on?? There are no exceptions being thrown anywhere.

For anyone who encounters this problem, it looks like the StackPanel was the issue. It seems that unless you specify a width and height on the StackPanel both it and its children will have a height and width of NaN which was causing the issue. Since I want the Height and Width to be 'Stretch,' I couldn`t use the StackPanel.
To resolve this, I changed from StackPanel to DockPanel. Problem solved

Related

Changing color rectangle inside button wpf

I am trying to achieve something that's driving me nuts, it partially works, but I can't achieve the same results that I did on my old Winforms project(I am trying to learn WPF and move away from Winforms).
I am trying to paint a Button if I place the mouse over it, so it change the background color and add a yellow rectangle on the left like this:
I tried to create with much difficulty a Styled button that partially do the job, it changes the background color but I can't figure out how to paint the yellow rectangle
<Style x:Key="MenuButton" TargetType="Button">
<Setter Property="Button.Background" Value="#525864"/>
<Setter Property="Button.Foreground" Value="#ffffff" />
<Setter Property="Button.BorderThickness" Value="0"/>
<Setter Property="Button.Margin" Value="10,0,0,0"/>
<Setter Property="Button.Height" Value="40"/>
<Setter Property="Button.Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
**
<Setter Property="Rectangle.Fill" Value="#f0e68c"/> **
<Setter Property="Button.Background" Value="#737b8c"/>
</Trigger>
</Style.Triggers>
</Style>
From the main Window I created the button like this:
<Button Style="{StaticResource MenuButton}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<Rectangle Grid.Column="0" Width="10"/>
<TextBlock Grid.Column="1" Text="Comparador Archivos" Margin="5,0,0,0"
HorizontalAlignment="Left" VerticalAlignment="Center"/>
<Image Grid.Column="2" Margin="5" Source="/Imagenes/icono_comparar.png"/>
</Grid>
</Button>
Because the Content in the ContentPresenter is set on the UI, the style does not know the existence of the Rectangle. Therefore, to access the Rectangle, you need to insert <Grid> ~ </Grid> directly instead of <ContentPresenter/>.
And in Style.Trigger, objects in the ControlTemplate is not accessible.
Therefore, it must be processed within ControlTemplate.Triggers.
By giving x:name to the Rectangle, internal properties can be accessed in Trigger.
<Style x:Key="MenuButton" TargetType="Button">
<Setter Property="Background" Value="#525864"/>
<Setter Property="Foreground" Value="#ffffff" />
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Margin" Value="10,0,0,0"/>
<Setter Property="Height" Value="40"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<Rectangle x:Name="rec" Grid.Column="0" Width="10"/>
<TextBlock Grid.Column="1" Text="Comparador Archivos" Margin="5,0,0,0"
HorizontalAlignment="Left" VerticalAlignment="Center"/>
<Image Grid.Column="2" Margin="5" Source="/Imagenes/icono_comparar.png"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="rec" Property="Fill" Value="#f0e68c"/>
<Setter Property="Background" Value="#737b8c"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Button Style="{StaticResource MenuButton}"/>
Cant you just change the fill hex so one of these
<Setter TargetName="rec" Property="Fill" Value="#f0e68c"/> <Setter Property="Background" Value="#737b8c"/>
Change the hex of Value="#hexcode"
Tell me if it works

How to create tab headers with arrows and dots in WPF

I am creating tabitem dynamically in WPF. I need to create the tab headers with arrows that shows a set of tab headers on arrow click like the below image.
For eg. If i have 10 tabs , 3 tabs should be shown initially then on clicking the next button, the next 3 tabs should be shown.
I found the tabpanel in the tab header template useful that displays the elements on multiple rows on more or less equal count in each row.
The code for the control template of the tab control as follows
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabControl}">
<Grid x:Name="templateRoot" ClipToBounds="true" SnapsToDevicePixels="true" KeyboardNavigation.TabNavigation="Local">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ColumnDefinition0"/>
<ColumnDefinition x:Name="ColumnDefinition1" Width="0"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition x:Name="RowDefinition0" Height="Auto"/>
<RowDefinition x:Name="RowDefinition1" Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Column="0" Background="#f7f7f7">
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition Width="0"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TabPanel x:Name="headerPanel" IsItemsHost="true" Margin="2,2,2,0" Grid.Row="0" KeyboardNavigation.TabIndex="1" Panel.ZIndex="1" Grid.Column="0"/>
</Grid>
</Grid>
<Border x:Name="contentPanel" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.Column="0" KeyboardNavigation.DirectionalNavigation="Contained" Grid.Row="1" KeyboardNavigation.TabIndex="2" KeyboardNavigation.TabNavigation="Local">
<Grid>
<ContentPresenter x:Name="PART_SelectedContentHost" ContentSource="SelectedContent" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Grid>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="TabStripPlacement" Value="Bottom">
<Setter Property="Grid.Row" TargetName="headerPanel" Value="1"/>
<Setter Property="Grid.Row" TargetName="contentPanel" Value="0"/>
<Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
<Setter Property="Height" TargetName="RowDefinition1" Value="Auto"/>
<Setter Property="Margin" TargetName="headerPanel" Value="2,0,2,2"/>
</Trigger>
<Trigger Property="TabStripPlacement" Value="Left">
<Setter Property="Grid.Row" TargetName="headerPanel" Value="0"/>
<Setter Property="Grid.Row" TargetName="contentPanel" Value="0"/>
<Setter Property="Grid.Column" TargetName="headerPanel" Value="0"/>
<Setter Property="Grid.Column" TargetName="contentPanel" Value="1"/>
<Setter Property="Width" TargetName="ColumnDefinition0" Value="Auto"/>
<Setter Property="Width" TargetName="ColumnDefinition1" Value="*"/>
<Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
<Setter Property="Height" TargetName="RowDefinition1" Value="0"/>
<Setter Property="Margin" TargetName="headerPanel" Value="2,2,0,2"/>
</Trigger>
<Trigger Property="TabStripPlacement" Value="Right">
<Setter Property="Grid.Row" TargetName="headerPanel" Value="0"/>
<Setter Property="Grid.Row" TargetName="contentPanel" Value="0"/>
<Setter Property="Grid.Column" TargetName="headerPanel" Value="1"/>
<Setter Property="Grid.Column" TargetName="contentPanel" Value="0"/>
<Setter Property="Width" TargetName="ColumnDefinition0" Value="*"/>
<Setter Property="Width" TargetName="ColumnDefinition1" Value="Auto"/>
<Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
<Setter Property="Height" TargetName="RowDefinition1" Value="0"/>
<Setter Property="Margin" TargetName="headerPanel" Value="0,2,2,2"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="TextElement.Foreground" TargetName="templateRoot" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
Now i get the output as
How to show this multiple rows into a single row with arrows to move to the next row. Any code samples will be helpful.
Basically, what you need is a custom scroll-view that wraps a custom itemspanel for the tab headers.
The following scrollviewer template places the scrollbar for horizontal scrolling left from the items instead of below - this effectively reduces it to the two scroll buttons. Also note, the PART_VerticalScrollBar is permanently collapsed in this template.
<ControlTemplate x:Key="ScrollViewerControlTemplate1" TargetType="{x:Type ScrollViewer}">
<Grid x:Name="Grid" Background="{TemplateBinding Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter" CanContentScroll="{TemplateBinding CanContentScroll}" CanHorizontallyScroll="False" CanVerticallyScroll="False" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Grid.Column="0" Margin="{TemplateBinding Padding}" Grid.Row="0"/>
<ScrollBar x:Name="PART_HorizontalScrollBar" AutomationProperties.AutomationId="HorizontalScrollBar" Cursor="Arrow" Grid.Column="1" Maximum="{TemplateBinding ScrollableWidth}" Minimum="0" Orientation="Horizontal" Grid.Row="0" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportWidth}"/>
<ScrollBar x:Name="PART_VerticalScrollBar" AutomationProperties.AutomationId="VerticalScrollBar" Cursor="Arrow" Grid.Column="1" Maximum="{TemplateBinding ScrollableHeight}" Minimum="0" Grid.Row="0" Visibility="Collapsed" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportHeight}"/>
</Grid>
</ControlTemplate>
Now, within the TabControl Template, you can replace the TabPanel by a horizontal StackPanel, wrapped in a ScrollViewer with above custom template:
...
<ScrollViewer VerticalScrollBarVisibility="Hidden" HorizontalScrollBarVisibility="Auto" Template="{DynamicResource ScrollViewerControlTemplate1}">
<StackPanel x:Name="headerPanel" Orientation="Horizontal" IsItemsHost="True" Grid.Column="0" Margin="2,2,2,0" Grid.Row="0" KeyboardNavigation.TabIndex="1" Panel.ZIndex="1"/>
</ScrollViewer>
...
This should roughly produce the desired UI and its a starting point to configure the desired behavior (like, how much do you scroll left and right with each click on the scroll arrows, ...)

List Tabitems in a dropdownlist wpf

I need to display all the tab headers in a dropdownlist.I have implemented the tab and added the down arrow button to it. I added a popup to list the items along with the button. But i cannot find a way to bind the header of the tab items to the list in the pop (Name = PresetPopup). I have tried binding the itemsource of "ConnectionList". But the ConnectionList is not recogonized in the ConnectionPages.xaml.cs file. Any code how to bind this will be helpful. Or any other way to do this?
<Style TargetType="{x:Type TabControl}">
<Setter Property="Padding" Value="2"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Background" Value="White"/>
<Setter Property="BorderBrush" Value="White"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabControl}">
<Grid x:Name="templateRoot" ClipToBounds="true" SnapsToDevicePixels="true" KeyboardNavigation.TabNavigation="Local">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ColumnDefinition0"/>
<ColumnDefinition x:Name="ColumnDefinition1" Width="0"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition x:Name="RowDefinition0" Height="Auto"/>
<RowDefinition x:Name="RowDefinition1" Height="*"/>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Grid.Column="0">
<TabPanel x:Name="headerPanel" Background="Transparent" IsItemsHost="true" Margin="2,2,2,0" Grid.Row="0" KeyboardNavigation.TabIndex="1" Panel.ZIndex="1"/>
<Border Height="30" VerticalAlignment="Center" BorderBrush="LightGray" BorderThickness="1">
<Grid>
<materialDesign:PackIcon Kind="ArrowDropDown" VerticalAlignment="Center" Width="15" />
<ToggleButton Name="OpenPopupButton" Background="Transparent" BorderBrush="Transparent" VerticalAlignment="Center">
<ToggleButton.Style>
<Style TargetType="{x:Type ToggleButton}">
<Setter Property="BorderThickness" Value="0"/>
</Style>
</ToggleButton.Style>
<materialDesign:PackIcon Background="White" Foreground="Black" Kind="ArrowDropDown" Height="15" VerticalAlignment="Center" Width="15" />
</ToggleButton>
<Popup Name="PresetPopup" IsOpen="{Binding ElementName=OpenPopupButton, Path=IsChecked}" PlacementTarget="{Binding ElementName=OpenPopupButton}" AllowsTransparency="True" PopupAnimation="Slide" StaysOpen="False" >
<ListBox Name="ConnectionList" ItemsSource="{Binding ConnectionsTab}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="a"></TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Popup>
</Grid>
</Border>
</StackPanel>
<Border x:Name="contentPanel" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.Column="0" KeyboardNavigation.DirectionalNavigation="Contained" Grid.Row="1" KeyboardNavigation.TabIndex="2" KeyboardNavigation.TabNavigation="Local">
<ContentPresenter x:Name="PART_SelectedContentHost" ContentSource="SelectedContent" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
...........
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Actually my final output requirement is similiar to this
final output

WPF Tab Control Headers on the left side

I want to make my custom tab control style. Headers should be on the left side and the content on the right side. Just like the standard styles can do it:
The selected element on the image above is the grid inside the active item. As you can see, it perfectly aligns next to the headers.
This is my design. The selected element is also the grid inside the active item, but it is just behind the headers instead of next to them. How can I align this grid next to the headers?
These are my styles for the tab item and tab control:
<Style TargetType="{x:Type TabControl}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabControl}">
<Grid KeyboardNavigation.TabNavigation="Local">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TabPanel
Name="HeaderPanel"
Grid.Row="0"
Panel.ZIndex="1"
Margin="0"
IsItemsHost="True"
KeyboardNavigation.TabIndex="1"
Background="AliceBlue" />
<Border
Name="Border"
Grid.Row="1"
BorderThickness="0"
KeyboardNavigation.TabNavigation="Local"
KeyboardNavigation.DirectionalNavigation="Contained"
KeyboardNavigation.TabIndex="2" >
<ContentPresenter
Name="PART_SelectedContentHost"
Margin="4"
ContentSource="SelectedContent" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type TabItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid>
<Border
Name="Border"
Margin="0"
Padding="10,4,4,4"
Background="Transparent"
Height="30"
Width="Auto"
BorderThickness="0">
<ContentPresenter x:Name="ContentSite"
VerticalAlignment="Center"
HorizontalAlignment="Left"
ContentSource="Header"
RecognizesAccessKey="True"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Panel.ZIndex" Value="100" />
<Setter TargetName="Border" Property="Background" Value="#FFFFFFFF" />
<Setter TargetName="Border" Property="BorderBrush" Value="#FF4576a9"></Setter>
<Setter TargetName="Border" Property="BorderThickness" Value="6, 0, 0, 0"></Setter>
<Setter TargetName="Border" Property="Padding" Value="4"></Setter>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border" Property="Background" Value="Yellow" />
<Setter Property="Foreground" Value="Orange" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Thank you.
In your Custom Template, you need to set Grid.Column instead of Grid.Row since your grid is now 2 cols/1 row instead of 1 col/2 rows
<ControlTemplate TargetType="{x:Type TabControl}">
<Grid ...>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TabPanel
Name="HeaderPanel" Grid.Column="0" ... />
<Border Name="Border" Grid.Column="1" ... >
<ContentPresenter ... />
</Border>
</Grid>
</ControlTemplate>
You need not to create a custom control. You can use TabStripPlacement property of tabcontrol to achieve this functionality.
<TabControl TabStripPlacement="Left">
<TabItem Header="Tab1">
</TabItem>
<TabItem Header="Tab2">
</TabItem>
</TabControl>
You can refer http://www.wpf-tutorial.com/tabcontrol/tab-positions/ or https://msdn.microsoft.com/en-us/library/system.windows.controls.tabcontrol.tabstripplacement(v=vs.110).aspx

Texbox with button in it

How can I create an TextBox in WPF ( With XAML ) that there is an button inside it, Just like Google Chrome Adressbar.
I want somethings like the picture below :
And then how can I change the position of the button to the right and left ? ( I'm using C# )
You could nest the button inside a Grid on top of the TextBox, since it sounds like you only need to use this once:
e.g.
<Grid>
<TextBox Text="Hello" />
<Button HorizontalAlignment="Right" Content="Click Me" />
</Grid>
The only issue with this is that the text will show under the button. An alternative is to make your own usercontrol or to edit the controltemplate of the textbox (but this will probably not have the functionality you want).
I'd create a textbox in the left column of a 2 column grid, then the button in the right column. Then remove the background and border on the textbox and put this background/border on the grid. This will give the appearance of a textbox with a button in where the text can't go underneath the button
e.g.
<Border BorderBrush="LightGray" BorderThickness="1" Height="30">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBox VerticalAlignment="Center" BorderBrush="Transparent" Background="Transparent" Text="Hello World this is a really long bit of text that wont go underneath the button (it will get clipped)"></TextBox>
<Button Content="Click me" Grid.Column="1" Margin="4"></Button>
</Grid>
</Border>
Only problem you have with that is that you don't get the chrome hover effect etc etc. Usercontrol with control template is your best option, but this gives you some ideas
The way to do this :
<Border x:Name="TextboxBorder" BorderBrush="#FFB8AAAA" BorderThickness="1" Grid.Column="2" Margin="3,1.5,4.084,1.5" Height="27" Background="White" CornerRadius="3">
<Grid x:Name="TextboxGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="33"/>
</Grid.ColumnDefinitions>
<Button x:Name="btn" Grid.Column="1" Margin="3.5,4.833,4.5,3.5" BorderBrush="{x:Null}" Style=" {DynamicResource SearchButtonStyle}" >
<Button.Background>
<ImageBrush ImageSource="Images/search.png"/>
</Button.Background>
</Button>
<TextBox Padding="0,1.2,0,0" x:Name="txt" Margin="1.541,0.5,2.041,0.5" TextWrapping="Wrap" Text="سلام" BorderThickness="0" FontSize="16"/>
</Grid>
</Border>
And the Button style is :
<Style x:Key="SearchButtonStyle" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/>
<Setter Property="Background" Value="{StaticResource ButtonNormalBackground}"/>
<Setter Property="BorderBrush" Value="{StaticResource ButtonNormalBorder}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border BorderThickness="0" Margin="1.875,0.5,1.75,-0.375" Background="{TemplateBinding Background}" Width="16" Height="16"/>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="true"/>
<Trigger Property="ToggleButton.IsChecked" Value="true"/>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And Then WPF Rocks!!!

Categories

Resources