Border per column header - wpf

I want to create a table on wpf that each column header has a round corner this is what i got so far:
as you can see, i have the desired outcome with a little un desired outcome.
the undesired out come is that the all data grid header itself (not the columns) is getting the same border, i need to make it transparent, how can i do that?
this is the part of the style:
<DataGrid.ColumnHeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="SeparatorBrush" Value="Transparent"/>
<Setter Property="Margin" Value="2"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
<Border CornerRadius="5 5 0 0" BorderThickness="1" BorderBrush="Black">
<TextBlock Text="{Binding }"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGrid.ColumnHeaderStyle>

for some reasons, DataGrid has a blank DataGridColumnHeader in its template. that blank columns doesn't have DataContext value (null). So change border brush to transparent in a DataTrigger:
<ControlTemplate>
<Grid>
<Border CornerRadius="5 5 0 0" BorderThickness="1" >
<TextBlock Text="{Binding}"/>
<Border.Style>
<Style TargetType="Border">
<Setter Property="BorderBrush" Value="Black"/>
<Style.Triggers>
<DataTrigger Binding="{Binding}" Value="{x:Null}">
<Setter Property="BorderBrush" Value="Transparent"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
</Grid>
</ControlTemplate>
improved version, which uses ContentPresenter in header template and test Content in a trigger
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Grid>
<Border CornerRadius="5 5 0 0" BorderThickness="1" >
<ContentPresenter/>
<Border.Style>
<Style TargetType="Border">
<Setter Property="BorderBrush" Value="Black"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Content, RelativeSource={RelativeSource TemplatedParent}}" Value="{x:Null}">
<Setter Property="BorderBrush" Value="Transparent"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
</Grid>
</ControlTemplate>
header is not necessary a text, e.g.:
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=Name}">
<DataGridTextColumn.Header>
<Border Background="Cyan">
<TextBlock Text="NAME" Margin="5"/>
</Border>
</DataGridTextColumn.Header>
</DataGridTextColumn>
</DataGrid.Columns>

Related

How to set Button Height dynamically in RowDetails RowHeaderTemplate

I have a datagrid with a Deails-View which shows another datagrid. This second grid is normally not shown. In the row header there is a button with a left arrow, when this is clicked, the details-grid is shown and the arrow changes to a down-arrow. This all works perfectly, but there is only a "small area" in the rowheader which accepts clicks. This is the code of my RowHeader-Template:
<DataGrid.RowHeaderTemplate>
<DataTemplate>
<Button Click="DataGridRowHeader_Button_Click" Cursor="Hand" HorizontalAlignment="Center" Width="40" >
<Button.Style>
<Style TargetType="Button">
<Style.Setters>
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid >
<Border Background="Chartreuse" BorderBrush="Black" BorderThickness="5"></Border>
<Path Fill="Blue" Data="M 0,0 14,7 0,14 Z" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow}},Path=DetailsVisibility}" Value="Visible">
<Setter Property="Background" Value="Salmon" />
<Setter Property="Height" Value="125" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}" >
<Grid >
<Border Background="LightCoral" BorderBrush="Black" BorderThickness="1" />
<Path Fill="Blue" Data="M 0,0 14,0 7,14 Z" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</DataTemplate>
</DataGrid.RowHeaderTemplate>
The line with
Setter Property = "Height" Value="125"
expands the button
but the button does not fit into the row header. With A small value, the button shrinks, and with a high button, the row header expands unnecessarily.
I tried to bind the Heigth-value to some parameters, e. g.
<Setter Property="Height" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGridRowDetailsEventArgs}}, Path=DetailsElement.ActualHeight}" />
(DataGridRowDetailsEventArgs captures the correct height-value when I look in code-behind:
private void dg_RowDetailsVisibilityChanged(object sender, DataGridRowDetailsEventArgs e)
{
Trace.WriteLine(e.DetailsElement.ActualHeight);
}
). Using
<Setter Property="Height" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGridRowDetails}}, Path=ActualHeight}" />
does not work either, the RowHeader is always expanded to a value which seems to be the height of the whole Master-Datagrid.
Any ideas how I can size the button correctly?
(Sorry for the colors, they are used only to see the different parts of the UI).
Hucky
I think your problem lies within the ControlTemplate of the DataGridRowHeader where you can't properly align content (in your case your Button)
Instead of overriding the ContentTemplate every single time with full Xaml I tried another approach by using a MarkupExtension(AlignmentControlTemplateExtension), which does the necessary steps for me (clone and adjust the default ControlTemplate), so that I only have to do something like this
<Setter Property="Template" Value="{AlignmentControlTemplate Type={x:Type WhatEverType}}" />
To solve your problem you have to do only some few steps
Set the DataGridRowHeader ControlTemplate
<DataGrid.RowHeaderStyle>
<Style TargetType="DataGridRowHeader">
<Setter Property="Template" Value="{stackoverflow:AlignmentControlTemplate Type={x:Type DataGridRowHeader}}"></Setter>
</Style>
</DataGrid.RowHeaderStyle>
Set VerticalContentAlignment and/or HorizontalContentAlignment however you like it (in your case VerticalContentAlignment=Stretch)
<DataGrid.RowHeaderStyle>
<Style TargetType="DataGridRowHeader">
<Setter Property="VerticalContentAlignment" Value="Stretch"></Setter>
<Setter Property="Template" Value="{stackoverflow:AlignmentControlTemplate Type={x:Type DataGridRowHeader}}"></Setter>
</Style>
</DataGrid.RowHeaderStyle>
Some adjustments in your Style.Triggers
Replace
<Setter Property="Height" Value="125" />
with
<Setter Property="VerticalAlignment" Value="Stretch" />
Edit Final Result
<DataGrid>
<!-- Step 1 -->
<DataGrid.RowHeaderStyle>
<Style TargetType="DataGridRowHeader">
<Setter Property="VerticalContentAlignment" Value="Stretch"></Setter> <!-- Step 2 -->
<Setter Property="Template" Value="{stackoverflow:AlignmentControlTemplate Type={x:Type DataGridRowHeader}}"></Setter>
</Style>
</DataGrid.RowHeaderStyle>
<!-- /Step 1 -->
<DataGrid.RowHeaderTemplate>
<DataTemplate>
<Button Click="DataGridRowHeader_Button_Click" Cursor="Hand" HorizontalAlignment="Center" Width="40" >
<Button.Style>
<Style TargetType="Button">
<Style.Setters>
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid >
<Border Background="Chartreuse" BorderBrush="Black" BorderThickness="5"></Border>
<Path Fill="Blue" Data="M 0,0 14,7 0,14 Z" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow}},Path=DetailsVisibility}" Value="Visible">
<Setter Property="Background" Value="Salmon" />
<Setter Property="VerticalAlignment" Value="Stretch" /> <!-- Step 3 -->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}" >
<Grid >
<Border Background="LightCoral" BorderBrush="Black" BorderThickness="1" />
<Path Fill="Blue" Data="M 0,0 14,0 7,14 Z" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</DataTemplate>
</DataGrid.RowHeaderTemplate>
...
</DataGrid>

WPF: add Combobox into GridViewColumn Header

So inside ListView.View i have this Style than i am using in order to remove Header borders:
<GridView ColumnHeaderContainerStyle="{StaticResource ListViewHeaderDefaultStyle}">
</GridView>
Style
<Style x:Key="ListViewHeaderDefaultStyle" TargetType="{x:Type GridViewColumnHeader}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GridViewColumnHeader}">
<Border BorderThickness="0,0,0,1" BorderBrush="{DynamicResource GridViewColumnHeaderBorderBrushColor}" Background="Transparent">
<TextBlock x:Name="ContentHeader"
Text="{TemplateBinding Content}"
Padding="0,5,0,0"
Width="{TemplateBinding Width}"
TextAlignment="Left"
FontSize="13"
Margin="5,0,0,0"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Foreground" Value="{DynamicResource GridViewColumnHeaderForegroundColor}"/>
<Setter Property="FontFamily" Value="{DynamicResource applicationFontFamily}"/>
<Setter Property="FontSize" Value="{DynamicResource GridViewColumnHeaderFontSize}"/>
</Style>
And inside my Column Header i want to add Combobox:
<GridViewColumn Width="100" CellTemplate="{StaticResource ComboBoxDataTemplate}">
<GridViewColumn.Header>
<StackPanel>
<ComboBox Width="90"
SelectedIndex="0"
SelectionChanged="ComboBox_SelectionChanged"
Margin="0,0,0,0">
<ComboBoxItem Content=" -- Select --"/>
<ComboBoxItem Content="File"/>
<ComboBoxItem Content="Name"/>
</ComboBox>
</StackPanel>
</GridViewColumn.Header>
But because my Style that i am using contains TextBlock i cannot see this Combobox.
If i removed the Style ListViewHeaderDefaultStyle this works fine but then all my Header borders that i want to remove visible again.
How can i use this style and also display my Header Combobox ?
try this style
<Style x:Key="ListViewHeaderDefaultStyle" TargetType="{x:Type GridViewColumnHeader}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GridViewColumnHeader}">
<Border BorderThickness="0,0,0,1" BorderBrush="{DynamicResource GridViewColumnHeaderBorderBrushColor}" Background="Transparent">
<Grid>
<TextBlock x:Name="ContentHeader"
Text="{TemplateBinding Content}"
Padding="0,5,0,0"
Width="{TemplateBinding Width}"
TextAlignment="Left"
FontSize="13"
Margin="5,0,0,0">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Visibility" Value="Visible"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ContentPresenter}" Value="{x:Null}">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<ContentPresenter HorizontalAlignment="Left" VerticalAlignment="Center"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Foreground" Value="{DynamicResource GridViewColumnHeaderForegroundColor}"/>
<Setter Property="FontFamily" Value="{DynamicResource applicationFontFamily}"/>
<Setter Property="FontSize" Value="{DynamicResource GridViewColumnHeaderFontSize}"/>
</Style>

Can someone explain me this behaviour about style and datatrigger?

Basically, i have a checkbox which has the IsChecked property binded in the viewmodel. This property is then evaluated inside a datatrigger to decide the color of a progress bar. The Progress bar itself, is styled with the code that i'm going to present.
Now, this code work:
<Style x:Key="CustomProgressBar" TargetType="ProgressBar">
<Style.Triggers>
<DataTrigger Value="True" Binding="{Binding Path=IsChecked}">
<Setter Property="Background" Value="Red"/>
</DataTrigger>
<DataTrigger Value="False" Binding="{Binding Path=IsChecked}">
<Setter Property="Background" Value="Yellow"/>
</DataTrigger>
</Style.Triggers>
<Setter Property="Template" >
<Setter.Value>
<ControlTemplate TargetType="ProgressBar">
<Border BorderBrush="{DynamicResource ProgressBorderBrushColor}" BorderThickness="0" Background="{DynamicResource ProgressBackgroundColor}" CornerRadius="0" Padding="0">
<Grid x:Name="PART_Track">
<Rectangle x:Name="PART_Indicator" HorizontalAlignment="Left">
<Rectangle.Style>
<Style TargetType="Rectangle">
<Setter Property="Fill" Value="{Binding}"/>
</Style>
</Rectangle.Style>
</Rectangle>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
while the following not:
<Style x:Key="CustomProgressBar" TargetType="ProgressBar">
<Setter Property="Template" >
<Setter.Value>
<ControlTemplate TargetType="ProgressBar">
<Border BorderBrush="{DynamicResource ProgressBorderBrushColor}" BorderThickness="0" Background="{DynamicResource ProgressBackgroundColor}" CornerRadius="0" Padding="0">
<Grid x:Name="PART_Track">
<Rectangle x:Name="PART_Indicator" HorizontalAlignment="Left">
<Rectangle.Style>
<Style TargetType="Rectangle">
<Style.Triggers>
<DataTrigger Value="True" Binding="{Binding Path=IsChecked}">
<Setter Property="Fill" Value="Red"/>
</DataTrigger>
<DataTrigger Value="False" Binding="{Binding Path=IsChecked}">
<Setter Property="Fill" Value="Yellow"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Can you tell me what is missing or what is wrong in the second xaml? (don't mind to the border part)
I think you have those backwards: the second example works, while the first does not.
The first example doesn't work because the Rectangle.Fill binding doesn't make sense. You're binding the Fill to whatever ProgressBar.DataContext is. Change the Rectangle definition to:
<Rectangle x:Name="PART_Indicator"
HorizontalAlignment="Left"
Fill="{TemplateBinding Background}" />
{TemplateBinding XYZ} is a short form of {Binding Path=XYZ, RelativeSource={RelativeSource TemplatedParent}. It means "bind to property XYZ on the control to which this template is applied". In this case, the template is applied to a ProgressBar, so we are binding Rectangle.Fill to the progress bar's Background. When your Setters update the background, the rectangle gets updated too.

How to get rid of the red border when a DataGrid cell is invalid?

How do I do this? I want to get rid of that annoying red border that shows on each invalid datagrid cell.
You can just add this line to your DataGrid:
<DataGrid Validation.ErrorTemplate="{x:Null}" />
I had this same issue but in my case I wasn't using IDataError or INotifyDataErrorInfo. I'm using a custom ValidationRule and styles to handle my validation logic and presentation. I was already using the DataGrid RowStyle to display a custom style for the row that has errors so I thought it would be easy to do something similar with the DataGridCell.
Things to note:
You can't just define a style and set the DataGrid.CellStyle. Instead you have to use the ElementStyle and/or the EditingElementStyle.
The style TargetType has to match the DataGridColumn type that the cell is using. So for a DataGridComboBoxColumn the TargetType should be ComboBox
DataGrid Column XAML:
<DataGridComboBoxColumn Header="Column1"
ItemsSource="{Binding Path=Column1Path}"
DisplayMemberPath="Column1DisplayPath"
ElementStyle="{StaticResource DGComboColValidationStyle}"
EditingElementStyle="{StaticResource DGComboColValidationStyle}">
<DataGridComboBoxColumn.SelectedItemBinding>
<Binding Path="Column1Path" UpdateSourceTrigger="LostFocus">
<Binding.ValidationRules>
<Validation:CustomValidationRule ValidationStep="UpdatedValue" ValidatesOnTargetUpdated="True" />
</Binding.ValidationRules>
</Binding>
</DataGridComboBoxColumn.SelectedItemBinding>
</DataGridComboBoxColumn>
Style Definitions
<Style x:Key="DGComboColValidationStyle" TargetType="{x:Type ComboBox}">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<Grid>
<Border BorderThickness="1"
BorderBrush="{Binding ElementName=adorner1, Path=DataContext[0].ErrorContent.ValidationType, Converter={StaticResource ValidationTypeColorConverter}}"
CornerRadius="3">
</Border>
<AdornedElementPlaceholder Name="adorner1"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="DGTextColValidationStyle" TargetType="{x:Type TextBlock}">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<Grid>
<Border BorderThickness="1"
BorderBrush="{Binding ElementName=adorner2, Path=DataContext[0].ErrorContent.ValidationType, Converter={StaticResource ValidationTypeColorConverter}}"
CornerRadius="3">
</Border>
<AdornedElementPlaceholder Name="adorner2"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="DGRowValidationStyle" TargetType="{x:Type DataGridRow}">
<Setter Property="ValidationErrorTemplate">
<Setter.Value>
<ControlTemplate x:Name="DGRowValidationTemplate">
<Grid>
<Ellipse Width="12" Height="12" Stroke="Black" StrokeThickness="0.5"
Fill="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridRow}}, Path=(Validation.Errors)[0].ErrorContent.ValidationType, Converter={StaticResource ValidationTypeColorConverter}}"/>
<TextBlock FontWeight="Bold" Padding="4,0,0,0"
Margin="0" VerticalAlignment="Top" Foreground="White" Text="!"
ToolTip="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridRow}}, Path=(Validation.Errors)[0].ErrorContent.ValidationMessage}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="BorderBrush" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent.ValidationType, Converter={StaticResource ValidationTypeColorConverter}}"/>
</Trigger>
<Trigger Property="Validation.HasError" Value="false">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="BorderBrush" Value="Transparent" />
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="DGCellStyle" TargetType="{x:Type DataGridCell}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="false">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridRow}}, Path=(Validation.Errors)[0].ErrorContent.ValidationMessage}"/>
</Trigger>
</Style.Triggers>
</Style>
Reference:
http://social.msdn.microsoft.com/Forums/vstudio/en-US/6d2d6513-7bca-4359-a12b-46da3c380b0a/wpf-4-datagrid-editingelementstyle-and-validationerrortemplate-adorner-layer?forum=wpf
Set the ValidatesOnDataErrors and ValidatesOnExpcetions to False for your binding of your cell.
In case you want your validations, then you have to override the Validation Template for your control. Please refer to my answer here -
Validation Error Style in WPF, similar to Silverlight
I hated the red border because it was put in the adorner and adorners sit on top of the window, meaning that if your element is partially/fully hidden by another element (like it is in a grid) the full adorner still shows :(
That didn't mean I didn't want some customization though, so I can still highlight my items in pink, or change their foreground and have the DataGridCell correctly clip everything off. You can do this by using a style trigger.
Hope this helps!
<DataGrid.Resources>
<Style TargetType="{x:Type TextBlock}" x:Key="TextBlockErrorStyle">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<!-- Just the adorned element means NO RED BORDER -->
<AdornedElementPlaceholder Name="controlWithError" />
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="Foreground" Value="Red"/>
<Setter Property="Background" Value="Pink"/>
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
...
<DataGridTemplateColumn Header="Description" MinWidth="150">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Description, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnValidationError=True}"
Style="{StaticResource ResourceKey=TextBlockErrorStyle}"
/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
You can check this as well
How to: Implement Validation with the DataGrid Control

WPF- trigger target not found

I have own style on listbox, I use in style data template and also control template.
In data template I create listbox item with some textboxes. In control template I want create a trigger which change foreground color of some textbox if listbox item is selected.
Here is some from style:
<Style x:Key="lbStyle" TargetType="{x:Type ListBox}">
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<Grid Name="MainGrid">
<TextBlock Name="tbName" Text="{Binding Value.nick}"
Grid.Column="0" Grid.Row="0" Margin="2,2,2,2"
FontSize="13" FontWeight="Medium"></TextBlock>
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="tbName" Property="Foreground" Value="Black"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Problem is, I get compile error : Cannot find the Trigger target tbName.
<Style TargetType="ListBox">
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding}" Margin="2" FontSize="13" FontWeight="Medium">
<TextBlock.Style>
<Style BasedOn="{StaticResource {x:Type TextBlock}}" TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ListBoxItem}, Path=IsSelected}" Value="True">
<Setter Property="Foreground" Value="Black"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
Your code of template is incorrect. You apply ListBoxItem template to ListBox template. Also, you didn't add anything inside ControlTemplate.
I have rewrited it:
<Style x:Key="itemStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<ContentPresenter x:Name="itemContent"/>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="itemContent" Property="TextBlock.Foreground" Value="Red"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
ListBox with applied style:
<ListBox ItemContainerStyle="{StaticResource itemStyle}" />

Resources