Restyling AvalonDock for high contrast themes? - c#

I'm using AvalonDock in a project. For the sake of this example, it is structured as follows:
<ad:DockingManager>
<ad:DockablePane>
<ad:DockableContent Title="Test1">
</ad:DockableContent>
<ad:DockableContent Title="Test2">
</ad:DockableContent>
</ad:DockablePane>
</ad:DockingManager>
This is fine, but unfortunately the tabs don't look so good on high contrast themes as shown below.
Ideally I would like to restyle the tabs to use a system color for the background (e.g. Window color). Is this possible?
Thanks,
Alan

go to codeplex and download avalon bits. There you should be able to quickly find their XAML files for styles. Take one as a baseline and start mocking with it.
you should see something like this (I'll include only one style)
<!--DockingManager-->
<Style x:Key="{x:Type ad:DockingManager}" TargetType="{x:Type ad:DockingManager}">
<Setter Property="Background" Value="{StaticResource DockManagerBackground}"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ad:DockingManager}">
<Grid Background="{TemplateBinding Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel Name="PART_LeftAnchorTabPanel"
Grid.Column="0" Grid.Row="1" Orientation="Vertical">
<StackPanel.Resources>
<Style TargetType="{x:Type ad:DockablePaneAnchorTabGroup}">
<Setter Property="LayoutTransform">
<Setter.Value >
<RotateTransform Angle="90"/>
</Setter.Value>
</Setter>
<Setter Property="Margin" Value="0,2,2,0"/>
</Style>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="0,0,3,3"/>
</Style>
</StackPanel.Resources>
</StackPanel>
<StackPanel Name="PART_RightAnchorTabPanel" Grid.Column="2" Grid.Row="1" Orientation="Vertical">
<StackPanel.Resources>
<Style TargetType="{x:Type ad:DockablePaneAnchorTabGroup}">
<Setter Property="LayoutTransform">
<Setter.Value >
<RotateTransform Angle="90"/>
</Setter.Value>
</Setter>
<Setter Property="Margin" Value="2,2,0,0"/>
</Style>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="3,3,0,0"/>
</Style>
</StackPanel.Resources>
</StackPanel>
<StackPanel Name="PART_TopAnchorTabPanel" Grid.Column="1" Grid.Row="0" Orientation="Horizontal"/>
<StackPanel Name="PART_BottomAnchorTabPanel" Grid.Column="1" Grid.Row="2" Orientation="Horizontal"/>
<Border
x:Name="PART_InternalContainer"
Background="{StaticResource DockManagerBorderBackground}"
Grid.Column="1" Grid.Row="1"
Padding="2">
<ContentPresenter />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
note that right on top of the file there will be a bunch of brushes, start with them, then start digging dipper

Related

Blurry ListBox text after modifying the number of Grid columns (WPF)

I have a Grid with the following definitions:
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="60"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="72"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="190"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
Inside that Grid, there is a ListBox which has an ItemContainerStyle:
<ListBox Grid.Column="2" ScrollViewer.HorizontalScrollbarVisibility="Disabled">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding MyTextProperty}"/>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem" BasedOn="{StaticResource ContainerStyle}"/>
</ListBox.ItemContainerStyle>
</ListBox>
The ItemContainerStyle being :
<Style x:Key="LbItemEquipement" TargetType="ListBoxItem">
<Style.Resources>
<Style TargetType="Border">
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="0" Direction="90" BlurRadius="7" Color="Black" Opacity="0.25"/>
</Setter.Value>
</Setter>
</Style>
</Style.Resources>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center">
<ContentPresenter.Resources>
<Style TargetType="TextBlock">
<Setter Property="TextWrapping" Value="Wrap"/>
<Setter Property="TextAlignment" Value="Center"/>
</Style>
</ContentPresenter.Resources>
</ContentPresenter>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="#Red"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontWeight" Value="DemiBold"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Height" Value="75"/>
<Setter Property="Background" Value="White"/>
<Setter Property="FontSize" Value="19"/>
</Style>
Everything was fine until I removed one column of the Grid:
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="60"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="190"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
Naturally, I changed the Column of the ListBox to 1 instead of 2.
However, the text of the ListBox is now kind of blurry. I tried playing with SnapsToDevicePixels and UseLayoutRounding, without success.
I know that it could also have something to do with the DropShadowEffect I apply on the ListBoxItem's border since when I remove it, the blur disappears.

How to fix a DataTemplate Grid's size and center visible content?

It's pretty hard to formulate this question without writing a novel...
I have a DataTemplate in a Style (applied to a TabItem if that matters), which provides a Grid containing two TextBlocks in a vertical fashion.
I'd like to be able to have my Grid staying the same size (height, in this case) and the first TextBlock centered (here, vertically) when the second TextBlock is collapsed (or hidden, I don't care).
How can I achieve that?
Here's what I have so far (the Text values are placeholders here, they're supposed to be bindings):
<Style TargetType="{x:Type TabControl}" x:Key="FlatTabControl">
<Style.Resources>
<Style TargetType="{x:Type TabItem}">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock VerticalAlignment="Center" Text="TOP/MIDDLE"/>
<TextBlock Grid.Row="1" Foreground="Green" Text="BOTTOM/COLLAPSED"/>
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Style.Resources>
</Style>
Do you mean something like this?
<Style TargetType="{x:Type TabControl}" >
<Style.Resources>
<Style TargetType="{x:Type TabItem}">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<Grid Width="150" Height="30">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock VerticalAlignment="Center" Text="TOP/MIDDLE" />
<TextBlock Grid.Row="1" Foreground="Green" Text="asdsad" Height="Auto" x:Name="TextTwo"/>
</Grid>
<DataTemplate.Triggers>
<Trigger SourceName="TextTwo" Property="Text" Value="">
<Setter TargetName="TextTwo" Property="Height" Value="0"/>
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Style.Resources>
</Style>

TabControl not working inside stackpanel

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

Bind Property in Template

I have the following HeaderTemplate for an Expander:
<Expander.HeaderTemplate>
<DataTemplate>
<Grid Background="#939393">
<Grid.RowDefinitions>
<RowDefinition Height="22"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.Resources>
<Style TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border HorizontalAlignment="Center" VerticalAlignment="Center" x:Name="border" CornerRadius="5,5,5,5"
Background="Transparent" BorderBrush="#FF000000" Margin="1" BorderThickness="1,1,1,1" SnapsToDevicePixels="True">
<ContentPresenter x:Name="contentPresenter"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Background" TargetName="border" Value="DarkGray"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<TextBlock Grid.Column="0" Background="#6E6E6E"/>
<ToggleButton Grid.Column="0" IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType=Expander}}" Focusable="False">
<Image Source="{Binding IsExpanded, RelativeSource={RelativeSource FindAncestor, AncestorType=Expander}, Converter={StaticResource boolToExpanderDirectionConverter}}"/>
</ToggleButton>
<TextBlock Grid.Column="1" Text="General" Margin="5,1,1,1" VerticalAlignment="Top" FontWeight="Bold"/>
</Grid>
</DataTemplate>
</Expander.HeaderTemplate>
This Headertemplate I have defined directly at one Expander. Now I want to move this Template to a Resource and apply it to all Expanders. My problem now is, that I don't know how to set the Header of the TextBlock in the Template to the Header of the Expander.
I knwo there's a way with TemplateBinding, but unfortunately I don't know how to use this.
TemplateBinding can only be used within a ControlTemplate.TemplateBinding is used for binding to the element properties within the template definition..
here in your example you have used controltemplate for toggleButton.
Example For TemplateBinding
<Style TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter TextElement.Foreground="{TemplateBinding Foreground}" x:Name="contentPresenter"/>
</Border>
<ControlTemplate.Triggers>
.....
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ToggleButton Grid.Column="0" Background="Red" BorderBrush="Black" BorderThickness="1" Foreground="White"/>
Here Border and Contentpresnter will bind properties of ToggleButton that is alreday defined in its defination.
But in your example you used Datatemplate..so you cant use TemplateBinding ..Please Follow This link for Binding Syntax.
Solution For Your example
Using Binding syntax we can bind Header property to different exapnder
Text="{Binding Path=Header,RelativeSource={RelativeSource AncestorType={x:Type Expander}}}"
<Window.Resources>
<DataTemplate x:Key="ExpanderHeaderTemplate">
<Grid Background="#939393">
<Grid.RowDefinitions>
<RowDefinition Height="22"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.Resources>
<Style TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border HorizontalAlignment="Center" VerticalAlignment="Center" x:Name="border" CornerRadius="5,5,5,5"
Background="{TemplateBinding Background}" BorderBrush="#FF000000" Margin="1" BorderThickness="1,1,1,1" SnapsToDevicePixels="True">
<ContentPresenter x:Name="contentPresenter"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Background" TargetName="border" Value="DarkGray"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<TextBlock Grid.Column="0" Background="#6E6E6E"/>
<ToggleButton Grid.Column="0" Background="Red" IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType=Expander}}" Focusable="False">
<Image Source="{Binding IsExpanded, RelativeSource={RelativeSource FindAncestor, AncestorType=Expander}, Converter={StaticResource boolToExpanderDirectionConverter}}"/>
</ToggleButton>
<TextBlock Grid.Column="1" Text="{Binding Path=Header,RelativeSource={RelativeSource AncestorType={x:Type Expander}}}" Margin="5,1,1,1" VerticalAlignment="Top" FontWeight="Bold"/>
</Grid>
</DataTemplate>
</Window.Resources>
<StackPanel>
<Expander Header="General1" HeaderTemplate="{StaticResource ExpanderHeaderTemplate}"/>
<Expander Header="General2" HeaderTemplate="{StaticResource ExpanderHeaderTemplate}"/>
</StackPanel>
you can have a idea of Template binding by below code i had implemented this when i was learning XAML.
<Button Template="{DynamicResource CircleButton}" Background="Green" Content="1"></Button>
<ControlTemplate x:Key="CircleButton" TargetType="{x:Type Button}">
<Grid HorizontalAlignment="Center" VerticalAlignment="Center" MinHeight="36" MinWidth="36">
<Ellipse Fill="{TemplateBinding Background}"></Ellipse>
<ContentPresenter TextBlock.FontFamily="Calibri" TextBlock.FontSize="24" TextBlock.Foreground="Wheat" HorizontalAlignment="Center" VerticalAlignment="Center"></ContentPresenter>
</Grid>
you have to give a x:Key to control Template and when you are binding it with some specific element define that x:key there like i did Template="{DynamicResource CircleButton}".
following is your case:
<Style TargetType="{x:Type Expander}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Expander}">
// Do your thing.
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
this will apply to all Expander throught your application. You can put this Style into App.xaml file for code cleanness. hope this'll help you.
Since you are specifying a HeaderTemplate via a DataTemplate, the DataContext of the template IS the Header. This simple example works:
<Expander Header="Test">
<Expander.HeaderTemplate>
<TextBlock Text="{Binding}"/>
</Expander.HeaderTemplate>
</Expander>

WPF DataGrid Column Header Resize with Custom Style

I have a WPF DataGrid (.NET 4) with custom template columns and header styles and would like to be able to adjust the size of the columns :
<DataGridTemplateColumn.HeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DataGridColumnHeader">
<StackPanel Orientation="Horizontal">
<Image Source="Images\monitor.png" Width="16" Height="16"/>
<TextBlock Text="Hostname" TextWrapping="Wrap" Padding="3"/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGridTemplateColumn.HeaderStyle>
Columns can still be sorted and re-arranged but not resized - the gripper does not show. I have seen this answer and looked at the Thumb control, however this seems like massive overkill to reproduce functionality already provided. The MSDN blog post references a StaticResource - RowHeaderGripperStyle which they don't provide!
I always do it this way and it works pretty fine:
<Style TargetType="DataGridColumnHeader">
<!-- here goes some setters -->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DataGridColumnHeader">
<Grid Margin="{TemplateBinding Padding}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<!-- some stuff, like border etc. -->
<ContentPresenter />
<Thumb x:Name="PART_RightHeaderGripper" Grid.Column="1"
HorizontalAlignment="Right"
Width="2" BorderThickness="1"
BorderBrush="{Binding VerticalGridLinesBrush, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"
Cursor="SizeWE"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Categories

Resources