I have used this xaml code to modify the background color of my DataGrid Header and the column separator visibility. My problem is that the column separators are elminated so the column headers look a little bit different:
this is my code :
<DataGrid AutoGenerateColumns="False" Grid.ColumnSpan="9" Grid.Row="1" Height="82" HorizontalAlignment="Left" Margin="99,427,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="363" Background="#9DB9EB" >
<DataGrid.Columns>
<DataGridTextColumn Header="Header1" />
<DataGridTextColumn Header="Header2" />
</DataGrid.Columns>
<DataGrid.ColumnHeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Background" Value="#cee8ef" />
<Setter Property="BorderThickness" Value="2" />
</Style>
</DataGrid.ColumnHeaderStyle>
</DataGrid>
How can I make the header column separtor visible?
Try this style
<Style TargetType="{x:Type DataGridColumnHeader}"
>
<Setter Property="Background"
Value="#cee8ef" />
<Setter Property="BorderThickness"
Value="2" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label
Content="{TemplateBinding Content}"
Grid.Column="0"
HorizontalAlignment="Center"
Margin="10,0,25,0" />
<Thumb HorizontalAlignment="Right"
Grid.Column="1"
Name="PART_HeaderGripper"
Margin="0,4,0,4"
Width="2"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Hope it helps you, you can modify it further if you need it ...
Related
The ContentTemplate code I use for the Datagrid Header is included in the relevant style file as follows:
<Style TargetType="{x:Type DataGrid}">
...
<Style.Resources>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding}" Margin="10 5" Grid.Column="0" />
<Button x:Name="btnFilter" Content="" FontFamily="{StaticResource FontAwesome}" FontSize="16" HorizontalAlignment="Right" Grid.Column="1" />
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Style.Resources>
...
</Style>
The resulting image from this code is as follows:
But I want to align the arrow icons to the right side as in the picture below. How can I do that?
Set the HorizontalContentAlignment property of the DataGridColumnHeaders to Stretch:
<Style TargetType="DataGridColumnHeader">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="ContentTemplate">
...
</Setter>
</Style>
I have used this xaml code to modify the background color of my DataGrid Header and the column separator visibility. My problem is that the column separators are elminated so the column headers look a little bit different:
this is my code :
<DataGrid AutoGenerateColumns="False" Grid.ColumnSpan="9" Grid.Row="1" Height="82" HorizontalAlignment="Left" Margin="99,427,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="363" Background="#9DB9EB" >
<DataGrid.Columns>
<DataGridTextColumn Header="Header1" />
<DataGridTextColumn Header="Header2" />
</DataGrid.Columns>
<DataGrid.ColumnHeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Background" Value="#cee8ef" />
<Setter Property="BorderThickness" Value="2" />
</Style>
</DataGrid.ColumnHeaderStyle>
</DataGrid>
How can I make the header column separtor visible?
Try this style
<Style TargetType="{x:Type DataGridColumnHeader}"
>
<Setter Property="Background"
Value="#cee8ef" />
<Setter Property="BorderThickness"
Value="2" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label
Content="{TemplateBinding Content}"
Grid.Column="0"
HorizontalAlignment="Center"
Margin="10,0,25,0" />
<Thumb HorizontalAlignment="Right"
Grid.Column="1"
Name="PART_HeaderGripper"
Margin="0,4,0,4"
Width="2"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Hope it helps you, you can modify it further if you need it ...
I have created a datagrid with a little customization.
The last column header is made up of the usual textblock plus a stackpanel under it with rotated text.
In order to make it look better I made the first 6 columns 25 in height with vertical alignment at the bottom, otherwise they would have stretched to the top.
My second image shows that I can reorder the last column.
However I can not reorder any of the first six.
In the next pics (Left) I removed the vertical alignment altogether making it sit in the center by default, (Right) I set the vertical alignment to the Top.
As you can see there must be another level of component, you cannot just alter the DataGridColumnHeader style and expect it to be reordered via dragging.
Questions:
What do I need to add to my style to bring the dragability down to sit with the lower DataGridColumnHeaders at the bottom, as in the first image?
How do I find this constraint? Can I iterate through the elements of the headers listing them out somehow?
And lastly the transparent floating dragged image of the column is aligned to the top I would like that brought down to sit at the bottom with the actual header labels, how to do?
Here is my XAML code:
<Window x:Class="DGTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="250" Width="500">
<Window.Resources>
<Style TargetType="DataGridColumnHeader">
<Setter Property="Background" Value="Transparent"/>
</Style>
<Style x:Key="ColumnHeaderStyle" TargetType="DataGridColumnHeader">
<Setter Property="Height" Value="25" />
<Setter Property="VerticalAlignment" Value="Bottom"/>
</Style>
</Window.Resources>
<Grid Name="gridUsers" Background="Transparent">
<DockPanel Background="Transparent">
<DataGrid Background="Transparent" CanUserReorderColumns="True" AutoGenerateColumns="False" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<DataGrid.Columns>
<DataGridTextColumn Header="ID" CanUserReorder="True" IsReadOnly="True" HeaderStyle="{StaticResource ColumnHeaderStyle}" Binding="{Binding Path=User_ID}"/>
<DataGridTextColumn Header="Name" CanUserReorder="True" CanUserSort="True" HeaderStyle="{StaticResource ColumnHeaderStyle}" Binding="{Binding Path=Name}"/>
<DataGridTextColumn Header="Username" CanUserReorder="True" CanUserSort="True" HeaderStyle="{StaticResource ColumnHeaderStyle}" Binding="{Binding Path=Username}"/>
<DataGridTextColumn Header="Job Title" CanUserReorder="True" CanUserSort="True" HeaderStyle="{StaticResource ColumnHeaderStyle}" Binding="{Binding Path=Job_Title}"/>
<DataGridTextColumn Header="Department" CanUserReorder="True" CanUserSort="True" HeaderStyle="{StaticResource ColumnHeaderStyle}" Binding="{Binding Path=Department}"/>
<DataGridTextColumn Header="Company" CanUserReorder="True" CanUserSort="True" HeaderStyle="{StaticResource ColumnHeaderStyle}" Binding="{Binding Path=Company}"/>
<DataGridTemplateColumn CanUserReorder="True" CanUserSort="False" >
<DataGridTemplateColumn.Header>
<StackPanel Orientation="Vertical" Background="Transparent" HorizontalAlignment="Center">
<Label Background="AliceBlue" HorizontalAlignment="Stretch" Height="25" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" >
Access
</Label>
<StackPanel Orientation="Horizontal" Background="Transparent" CanVerticallyScroll="False" CanHorizontallyScroll="False">
<TextBlock Text="Read" Width="80" Margin="20,1,0,1" >
<TextBlock.LayoutTransform>
<RotateTransform Angle="-60"/>
</TextBlock.LayoutTransform>
</TextBlock>
<TextBlock Text="Write" Width="80" Margin="-15,1,0,1" >
<TextBlock.LayoutTransform>
<RotateTransform Angle="-60"/>
</TextBlock.LayoutTransform>
</TextBlock>
<TextBlock Text="Administrator" Width="80" Margin="-15,1,0,1" >
<TextBlock.LayoutTransform>
<RotateTransform Angle="-60"/>
</TextBlock.LayoutTransform>
</TextBlock>
</StackPanel>
</StackPanel>
</DataGridTemplateColumn.Header>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</DockPanel>
</Grid>
</Window>
I tried to fulfill your requirement with the following changes. Change the ColumnHeaderStyle as given below. I just given raw style of column headers with the following changes. Change that as per your application needs.
<Style TargetType="DataGridColumnHeader">
<Setter Property="Background" Value="Transparent"/>
</Style>
<Style x:Key="ColumnHeaderStyle" TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="VerticalContentAlignment" Value="Bottom"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DataGridColumnHeader">
<Grid>
<Border Background="Gray" VerticalAlignment="Bottom" Margin="1">
<ContentPresenter Content="{TemplateBinding Content}" Margin="5" VerticalAlignment="Bottom"/>
</Border>
<Thumb x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left">
<Thumb.Style>
<Style TargetType="{x:Type Thumb}">
<Setter Property="Width" Value="8"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Cursor" Value="SizeWE"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Thumb.Style>
</Thumb>
<Thumb x:Name="PART_RightHeaderGripper" HorizontalAlignment="Right">
<Thumb.Style>
<Style TargetType="{x:Type Thumb}">
<Setter Property="Width" Value="8"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Cursor" Value="SizeWE"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Thumb.Style>
</Thumb>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Also set the DragIndicatorStyle of all columns as given below.
<Style x:Key="DragIndicatorStyle" TargetType="Control">
<Setter Property="Height" Value="75"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Margin" Value="0,-25,0,0"/>
<Setter Property="VerticalAlignment" Value="Bottom"/>
<Setter Property="VerticalContentAlignment" Value="Bottom"/>
</Style>
I think your problem is to do with making the Header only 25 high removes the correct drag/drop targets which is why it doesn't work correctly.
Putting a custom Header on each row seems to give the behaviour you desire. In this case as it is being wrapped in a Grid, there is a control filling the entire space so the drag/drop can work correctly. (The styling of the header could be moved to a Style I think rather than repeating it on each column). I think there must be a better way than giving the stack panel a size of 90 but I can't find a better way at the moment.
<DataGridTextColumn CanUserReorder="True" CanUserSort="True" Binding="{Binding Path=Company}">
<DataGridTextColumn.Header>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="25"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Height="90" Grid.Row="0"/>
<TextBlock Height="25" Grid.Row="1">Access</TextBlock>
</Grid>
</DataGridTextColumn.Header>
</DataGridTextColumn>
My Textblock isn't wrapping unless I give it a fixed width. The problem is that I don't know what the width should be, as it needs to simply take up whatever's left.
<Style TargetType="TextBlock" x:Key="Label">
<Setter Property="FontSize" Value="20" />
</Style>
<Style TargetType="TextBlock" x:Key="Value">
<Setter Property="TextWrapping" Value="Wrap" />
<Setter Property="FontSize" Value="16" />
</Style>
<localControls:DetailRegion>
<StackPanel Orientation="Horizontal" Width="230">
<TextBlock Text="Beliefs and Goals:" Style="{StaticResource Label}" />
<TextBlock Text="{Binding BeliefsAndGoals}" Style="{StaticResource Value}" />
</StackPanel>
</localControls:DetailRegion>
Ugh. As always, the problem is the StackPanel. If I switch to a grid with two columns (one auto, the other *) then it works as expected.
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="Beliefs & Goals:" Style="{StaticResource Label}" />
<TextBlock Text="{Binding BeliefsAndGoals}" Style="{StaticResource Value}" Grid.Column="1" />
</Grid>
How do I get alternating colors on a ItemsControl? I have AlternationCount set to 2, but the ItemsControl.AlternationIndex property always returns 0.
<ItemsControl ItemsSource="{Binding}" AlternationCount="2">
<ItemsControl.Resources>
<Style x:Key="FooBar" TargetType="Grid">
<Style.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Background" Value="Blue"/>
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
</ItemsControl.Resources>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="0,0,0,10" Style="{StaticResource FooBar}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions >
<RowDefinition Height="Auto" />
<!--<RowDefinition Height="Auto" />-->
</Grid.RowDefinitions>
<CheckBox IsChecked="{Binding Checked, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Center" />
<Label Grid.Column="1" Content="{Binding CompanyName}" />
<Label Grid.Column="2" Content="{Binding TradeKey}" />
<Label Grid.Column="3" Content="{Binding TradeDate}" ContentStringFormat="d" />
<Label Grid.Column="4" Content="{Binding Cusip}" />
<Label Grid.Column="5" Content="{Binding IssueName}" />
<Label Grid.Column="6" Content="{Binding TotalUnits}" ContentStringFormat="N0" />
<!--<Expander Grid.Row="0" Grid.Column="7" Grid.ColumnSpan="7" IsExpanded="True">
<Expander.Header>
<StackPanel Orientation="Horizontal">
<Label Content="Allocations"/>
<Button Content="Edit" Name="cmdEdit" Click="cmdEdit_Click" />
</StackPanel>
</Expander.Header>-->
<DataGrid Grid.Column="7" IsReadOnly="True" ItemsSource="{Binding Territories}" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Rep on Ticket" Binding="{Binding TradeCustomer.RepNameNotes}" />
<DataGridTextColumn Header="Rep # on Ticket" Binding="{Binding TradeCustomer.RepNumberNotes}" />
<DataGridTextColumn Header="State" Binding="{Binding TradeCustomer.AccountStateKey}" />
<DataGridTextColumn Header="Qty. on Ticket" Binding="{Binding TradeCustomer.Quantity, StringFormat=N0}" />
<DataGridTextColumn Header="Zip Code" Binding="{Binding ZipCode}" />
<DataGridTextColumn Header="State" Binding="{Binding State}" />
<DataGridTextColumn Header="Territory" Binding="{Binding Territory}" />
</DataGrid.Columns>
</DataGrid>
<!--</Expander>-->
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Template>
<ControlTemplate>
<Border BorderThickness="{TemplateBinding Border.BorderThickness}" Padding="{TemplateBinding Control.Padding}" BorderBrush="{TemplateBinding Border.BorderBrush}" Background="{TemplateBinding Panel.Background}" SnapsToDevicePixels="True">
<ScrollViewer Padding="{TemplateBinding Control.Padding}" Focusable="False">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
</ControlTemplate>
</ItemsControl.Template>
</ItemsControl>
Check here http://www.codeproject.com/Articles/35886/WPF-ItemsControl-with-alternating-items-and-hover-.aspx
You have to change your code like this to get it working
<ItemsControl ItemsSource="{Binding DataList}" AlternationCount="2">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid x:Name="FooBar" Margin="0,0,0,10">
----------------------------
----------------------------
</Grid>
<DataTemplate.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Background" Value="Blue" TargetName="FooBar"/>
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="Red" TargetName="FooBar"/>
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
Here is an alternative which may be a bit more general
<DataTemplate x:Key="AlternatingTemplate">
<Border>
<Border.Style>
<Style TargetType="{x:Type Border}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=(ItemsControl.AlternationIndex),
RelativeSource={RelativeSource AncestorType={x:Type ContentPresenter}}}"
Value="0">
<Setter Property="Background" Value="White" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=(ItemsControl.AlternationIndex),
RelativeSource={RelativeSource AncestorType={x:Type ContentPresenter}}}"
Value="1">
<Setter Property="Background" Value="LightGray" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<ContentPresenter Content="{Binding}" />
</Border>
</DataTemplate>
Usage:
<ItemsControl AlternationCount="2"
ItemTemplate="{StaticResource AlternatingTemplate}"
ItemsSource="{Binding SourceOfData}" />
If you don't want to use the DataTemplate approach, you can create a custom control that uses a ContentControl as the item container, therefore allowing you to specify a background color.
Class:
public class ItemsControlAlternating : ItemsControl
{
static ItemsControlAlternating()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ItemsControlAlternating),
new FrameworkPropertyMetadata(typeof(ItemsControlAlternating)));
}
protected override DependencyObject GetContainerForItemOverride()
{
return new ContentControl();
}
protected override bool IsItemItsOwnContainerOverride(object item)
{
return item is ContentControl;
}
}
Resource Dictionary:
<Style TargetType="{x:Type c:ItemsControlAlternating}">
<Setter Property="AlternationCount" Value="2"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type c:ItemsControlAlternating}">
<ItemsPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="{x:Type ContentControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ContentControl}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Background" Value="Gray"/>
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
</Setter.Value>
</Setter>
</Style>