WPF: add Combobox into GridViewColumn Header - wpf

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>

Related

Watermark/Placeholder on a WPF Combobox control

I can do the watermark text/placeholder on a WPF textbox control by using the below XAML code.
<TextBox Name="txtFilter" Grid.Row="1" Height="25" Width="250" BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" Margin="5,0,0,0" TextChanged="txtFilter_TextChanged">
<TextBox.Style>
<Style BasedOn="{StaticResource {x:Type TextBox}}" TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border Background="White" CornerRadius="5" BorderBrush="Black" BorderThickness="1">
<Grid>
<ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
<TextBlock x:Name="textBlock" VerticalAlignment="Center" Opacity="0.5" Text=" Search by Customer Name " Foreground="Blue" FontStyle="Italic" Visibility="Hidden" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsFocused" Value="False" />
<Condition Property="Text" Value="" />
</MultiTrigger.Conditions>
<Setter Property="Visibility" TargetName="textBlock" Value="Visible" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TextBox.Style>
</TextBox>
But how it is possible for a WPF Combo box control ? I tried with the below shown XAML code. But it is not working.
<ComboBox.Resources>
<VisualBrush x:Key="HelpBrush" TileMode="None" Opacity="0.4" Stretch="None" AlignmentX="Left">
<VisualBrush.Visual>
<TextBlock FontStyle="Italic" Opacity="0.5" Text="Type or select from list" Foreground="Blue" Visibility="Visible"/>
</VisualBrush.Visual>
</VisualBrush>
</ComboBox.Resources>
<ComboBox.Style>
<Style TargetType="ComboBox">
<Style.Triggers>
<Trigger Property="Text" Value="{x:Null}">
<Setter Property="Background" Value="{StaticResource HelpBrush}"/>
</Trigger>
<Trigger Property="Text" Value="">
<Setter Property="Background" Value="{StaticResource HelpBrush}"/>
</Trigger>
</Style.Triggers>
</Style>
</ComboBox.Style>
Can anyone help me to place a watermark text on a WPF Combobox control ???

How to create and bind control template for listview with gridview WPF

I have code in xaml and trying create controlTemplae
<ListView Name="seznamSkupin" Background="White" Grid.Row="1" Grid.Column="0" BorderBrush="#a9a9a9" BorderThickness="0,0,1,0" Padding="0,30">
<ListView.ItemContainerStyle>
<Style>
...structure...
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView ColumnHeaderContainerStyle="{StaticResource gridViewHeader}">
<GridViewColumn DisplayMemberBinding="{Binding NazevSkupiny }"/>
</GridView>
</ListView.View>
</ListView>
Data are in code behind
List<Skupina> skupina = new List<Skupina>();
string[] skupiny = {"Test", "3.A", "3.B"};
for (int i = 0; i < skupiny.Length; i++)
{
skupina.Add(new Skupina() { NazevSkupiny = skupiny[i]});
}
seznamSkupin.ItemsSource = skupina;
It works in xaml, but I need to create template for listView, - I have two listViews and nedd to use same styles. I am using separate style.xaml, trying this, but content of "seznamSkupin" is not showed:
<Style x:Key="dialogListView" TargetType="{x:Type ListView}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListView}">
<ListView Background="{StaticResource color3}" BorderThickness="0" Padding="0,30">
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center"/>
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="FontFamily" Value="{StaticResource fontFamilyDefault}" />
<Setter Property="FontSize" Value="{StaticResource fontSize3}" />
<Setter Property="Foreground" Value="{StaticResource color5 }" />
<Setter Property="Margin" Value="12,0"/>
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<Border CornerRadius="0" SnapsToDevicePixels="True"
BorderThickness="0,0,0,1"
BorderBrush="Black"
Background="{TemplateBinding Background}"
>
<Border x:Name="InnerBorder" CornerRadius="0" BorderThickness="0,3,0,3" BorderBrush="white" Padding="0,3" >
<Grid>
<GridViewRowPresenter VerticalAlignment="Center" HorizontalAlignment="Left" SnapsToDevicePixels="True" Content="{TemplateBinding Content}" Columns="{TemplateBinding GridView.ColumnCollection}" />
</Grid>
</Border>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" Value="{StaticResource color1}" />
<Setter Property="Foreground" Value="{StaticResource color4}" />
<Setter Property="BorderBrush" Value="Transparent" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
</ListView>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I think, problem is in GridViewRowPresenter can anybody help? Thanks!

StaticResource alters border of TextBox

I needed a placeholder for TextBox and found this working code:
<Style x:Key="placeHolder" TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<TextBox Text="{Binding Path=Text,
RelativeSource={RelativeSource TemplatedParent},
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"
x:Name="textSource"
Background="Transparent"
Panel.ZIndex="2"
BorderThickness="0,0,0,1"/>
<TextBox Text="{TemplateBinding Tag}" Background="{TemplateBinding Background}" Panel.ZIndex="1">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Foreground" Value="Transparent"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Text, Source={x:Reference textSource}}" Value="">
<Setter Property="Foreground" Value="LightGray"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This is my TextBox:
<TextBox x:Name="isci_tb" HorizontalAlignment="Left" Height="25" Margin="0,0,0,0" TextWrapping="Wrap"
VerticalAlignment="Center" Width="120" BorderThickness="0, 0, 0, 1" TextChanged="isci_tb_TextChanged" Tag="išči" Style="{StaticResource placeHolder}">
<TextBox.Background>
<ImageBrush/>
</TextBox.Background>
</TextBox>
Since I am new to XAML I don't see where or what changes the border of my button. I wish to only have the bottom border but instead all 4 borders are shown.
Set the BorderThickness property of the inner TextBox in your template to 0:
<Style x:Key="placeHolder" TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<TextBox Text="{Binding Path=Text,
RelativeSource={RelativeSource TemplatedParent},
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"
x:Name="textSource"
Background="Transparent"
Panel.ZIndex="2"
BorderThickness="0,0,0,1"/>
<TextBox Text="{TemplateBinding Tag}" Background="{TemplateBinding Background}" Panel.ZIndex="1"
BorderThickness="0">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Foreground" Value="Transparent"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Text, Source={x:Reference textSource}}" Value="">
<Setter Property="Foreground" Value="LightGray"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Border per column header

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>

AdornerDecorator and tab stop issues

I am using IDataErrorInfo to validate and indicate errors in my text boxes. I am finding I have to tab once for the text box and once for the adornerdecorator.
I have an error template:
<ControlTemplate x:Key="ErrorTemplate">
<StackPanel KeyboardNavigation.IsTabStop="False" >
<Border KeyboardNavigation.IsTabStop="False" BorderBrush="Red" BorderThickness="1" Padding="2" CornerRadius="2">
<AdornedElementPlaceholder KeyboardNavigation.IsTabStop="False" />
</Border>
</StackPanel>
</ControlTemplate>
a textbox template:
<Style x:Key="TextBoxInError" TargetType="{x:Type TextBox}">
<Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Margin" Value="0,5,0,5"/>
<Setter Property="AllowDrop" Value="true"/>
<Setter Property="HorizontalContentAlignment" Value="left"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid KeyboardNavigation.IsTabStop="False" >
<Border KeyboardNavigation.IsTabStop="False" x:Name="Border" Background="{DynamicResource WindowBackgroundBrush}" BorderBrush="{DynamicResource SolidBorderBrush}" BorderThickness="1" Padding="2" CornerRadius="2">
<ScrollViewer IsTabStop="False" Margin="0" x:Name="PART_ContentHost" Style="{DynamicResource SimpleScrollViewer}" Background="{TemplateBinding Background}"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors), Converter={StaticResource errorConverter}}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="Gray"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
and declare a text box like this:
<AdornerDecorator KeyboardNavigation.IsTabStop="False" >
<TextBox Margin="5,5,5,3" x:Name="txtName" IsEnabled="{Binding EditMode}" Validation.ErrorTemplate="{StaticResource ErrorTemplate}"
Text="{Binding ApplicationName, Mode=TwoWay, ValidatesOnExceptions=True, NotifyOnValidationError=True, ValidatesOnDataErrors=True}"
Height="25" MaxLength="50" MaxLines="1" Style="{StaticResource TextBoxInError}"/>
</AdornerDecorator>
If the adorner is round one text box as above then I tab once to leave the text box and once to leave the 'adornment' (it seems) If I have the adorner around a stackpanel of text boxes then I tab once each for the text boxes then have to go back through all the 'adornments' in turn. When tabbing through the adornments the focus goes on the red border defined in the control template..
any ideas?
thanks
Add this to the window's resources section:
<Style TargetType="{x:Type Control}">
<Setter Property="Focusable" Value="False"/>
</Style>
For more information look at my blog: http://www.nbdtech.com/blog/archive/2008/05/25/WPF-Problems-with-Keyboard-Focus-When-Using-Validation.aspx

Resources