WPF Datagrid ColumHeader MouseOver Close button - wpf

When I do mouse over on column header of datagrid, its close button should popup with header to remove column.
I have below XAML to capture mouseover of header.
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="Height" Value="26" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{DynamicResource ActiveItemButtonPressedBrush}" />
?????????? what should I write here to create that button ??????????
</Trigger>
</Style.Triggers>
</Style>
Please help me to generate XAML as I am new to WPF.

you need to override DataGrid Column's HeaderTemplate as a
....
<DataTemplate>
<Button>
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
... do you contents here
..text block as visible
<Button x:Name="btn"..round button as collapsed
<ControlTemplate.Triggers>
<Trigger Property="Button.IsMouseOver" Value="True">
<Setter Property="Background" Value="{DynamicResource ActiveItemButtonPressedBrush}" />
<Setter TargetName="btn" Property="Visibility" Value="Visible"/>
</Trigger>
</Setter>

Related

Getting rid of double Tabing in WPF Data Grid

The last to columns of my Data grid are read only and are supposed to ignore the tab completely since I set the Focusable property to False. The Data Grid is not custom it is only styled.
I canĀ“t get the Tab to ignore the last two columns. I would like to jump from the 8th column right to the beginning of the next row. Instead, I have to tab through the last two columns before I get to the next row.
<Style x:Key="DataGridCellFocusVisualStyle">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle StrokeThickness="2"
Stroke="{StaticResource DarkGrayBrush}"
SnapsToDevicePixels="true"
Margin="-5 0 0 0"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="DataGridCellStyle" TargetType="{x:Type DataGridCell}">
<Setter Property="BorderBrush" Value="{StaticResource DarkGrayBrush}" />
<Setter Property="BorderThickness" Value="0 0 1 0" />
<Setter Property="KeyboardNavigation.IsTabStop" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<ContentControl Margin="5 0 0 0" Content="{TemplateBinding Content}"
FocusVisualStyle="{StaticResource DataGridCellFocusVisualStyle}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True" >
<Setter Property="Foreground" Value="{StaticResource BlackBrush}"/>
<Setter Property="Background" Value="{StaticResource WhiteBrush}"/>
</Trigger>
<Trigger Property="IsReadOnly" Value="True">
<Setter Property="IsTabStop" Value="False"/>
</Trigger>
</Style.Triggers>
</Style>
This is the Column I want to jump over.
The Cell style is based on the CellStyle that we see in DataGridCellStyle in the XAML on top.
<Style x:Key="CalculationNumericColumnCellStyle"
BasedOn="{StaticResource LeschacoDataGridCellStyle}"
TargetType="{x:Type DataGridCell}">
<Setter Property="TextBlock.TextAlignment" Value="Right" />
</Style>
Try the following style, it will skip all the columns where you have placed IsReadOnly = "True".
<Style TargetType="{x:Type DataGridCell}">
<Style.Triggers>
<Trigger Property="IsReadOnly" Value="true">
<Setter Property="IsTabStop" Value="False"/>
</Trigger>
</Style.Triggers>
</Style>
I answered my own question yet again. I saw that when I apply a Template to this part of the Data Grid, the Data Grid Cell seems to be seen by the TabManager as two controls in the visual tree. So the Focus Visual Style of the Data Grid Cell was the Dotted Rectangle and the Focus Visual Style of the Template was the Continuous Rectangle. So, lesson learned here is that you should not apply Templates to controls unless you absolutely have to. Heres the new XAML implementation of the Data Grid Cell if anyone is interested.
<Style x:Key="DataGridCellStyle" TargetType="{x:Type DataGridCell}">
<Setter Property="BorderBrush" Value="{StaticResource DarkGrayBrush}" />
<Setter Property="BorderThickness" Value="0 0 1 0" />
<Setter Property="FocusVisualStyle" Value="{StaticResource DataGridCellFocusVisualStyle}"/>
<!--<Setter Property="VerticalAlignment" Value="Center"/>-->
<!--<Setter Property="Padding" Value="-20 0 0 0"/>-->
<Setter Property="Margin" Value="5 0 0 0"/>
<Style.Triggers>
<Trigger Property="DataGridCell.IsSelected" Value="True" >
<Setter Property="Background" Value="{StaticResource LightBlueBrush}"/>
<Setter Property="Foreground" Value="{StaticResource BlackBrush}"/>
</Trigger>
<Trigger Property="IsReadOnly" Value="True">
<Setter Property="IsTabStop" Value="False"/>
</Trigger>
</Style.Triggers>
</Style>

How to set a border around listviewitem in WPF

My ListView should have following style:
no border around the whole ListView (achieved)
no highlighting when interacting with ListViewItem (achieved)
border around selected ListViewItem (missing)
My ListView:
<ListView DisplayMemberPath="Name" BorderThickness="0" >
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<!-- get rid of the highlighting -->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
<!-- style selected item -->
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontSize" Value="20" />
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
</ListView>
I tried this and this, both doesn't work for me. I guess my problem is the template but I have no idea how to put a border around the selected ListViewItem.
Update
Working solution:
<ListView DisplayMemberPath="Name" BorderThickness="0" >
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<!-- get rid of the highlighting -->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<Border x:Name="Border">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontSize" Value="20" />
<Setter Property="FontWeight" Value="Bold" />
<Setter TargetName="Border" Property="BorderBrush" Value="Black"/>
<Setter TargetName="Border" Property="BorderThickness" Value="2"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
</ListView>
Maybe this works. Add a Border around ContentPresenter an use controlTemplate Triggers
<ControlTemplate TargetType="{x:Type ListViewItem}">
<Border x:Name="Border">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontSize" Value="20" />
<Setter Property="FontWeight" Value="Bold" />
<Setter TargetName="Border" Property="BorderBrush" Value="Red"/>
<Setter TargetName="Border" Property="BorderThickness" Value="1"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>

How to set a global style to XAML buttons that have exisiting control templates

I'm attempting to create a global style so that the mouse cursor will change to a hand when mouseover on any button in the app. However, my buttons have their own control templates that use the IsMouseOver trigger so my global IsMouseOver trigger isn't working. Is there any way to get around this without having to add the setter for the trigger to every button style?
Here is the global style:
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand"/>
</Trigger>
</Style.Triggers>
</Style>
And here is a button:
<Style x:Key="VideoVolumeButtonBaseStyle" TargetType="{x:Type Button}">
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Foreground" Value="{StaticResource DefaultColorBrush}"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Height" Value="27"/>
<Setter Property="Width" Value="31"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="ContentBorder" CornerRadius="3" Background="Transparent" BorderBrush="Transparent" BorderThickness="2">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<ContentPresenter Name="contentPresenter" Content="{TemplateBinding Content}" VerticalAlignment="Center" HorizontalAlignment="Left"/>
</StackPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsDefaulted" Value="true"/>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Foreground" Value="{StaticResource FocusedColorBrush}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Foreground" Value="{StaticResource FocusedColorBrush}"/>
<Setter Property="Margin" Value="1,-2,0,0" TargetName="contentPresenter"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{StaticResource DisabledColorBrush}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
You can just use the Style.BasedOn property to base your later Styles on your global Style:
<Style x:Key="GlobalStyle" TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand"/>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="ButtonStyle" TargetType="{x:Type Button}"
BasedOn="{StaticResource GlobalStyle}">
...
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
...
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
If you don't want to name your global Style, you can simply base it on this named Style:
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource GlobalStyle}" />

EditMode in DataGrid with single click via XAML triggers

I have DataGrid, if I want edit value in cell I must perform double click for on this and cursor appear here (with one click it just select appropriate cell)..!
May I make (via Xaml triggers) that with single click on cells they aren't just selected, but entered in EditMode at once and when I switch between cells with arrows they also enter in EditMode?
Here my current revised code
<Page.Resources>
<grd:LenghthToVisibility x:Key="LenghthToVisibility"/>
<grd:StringToSystemIconConverter x:Key="StringToSystemIconConverter"/>
<grd:booleanConverter x:Key="booleanConverter"/>
<DataGrid.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="IsTabStop" Value="False" />
<Setter Property="Focusable" Value="False" />
</Style>
<Style x:Key="RightCellStyle" TargetType="DataGridCell">
<Setter Property="HorizontalAlignment" Value="Right" />
</Style>
<Style x:Key="RightAlignedCell" TargetType="{x:Type DataGridCell}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Right" VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="DataGridCell.IsSelected" Value="True">
<Setter Property="IsEditing" Value="True" />
<Setter Property="Background" Value="#356815" />
<Setter Property="Foreground" Value="#e2fce2" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.CellStyle>
</Page.Resources>
Thanks.
I have 2 strange errors and refresh my code above:
1) "Error 5 The attachable property 'CellStyle' was not found in type 'DataGrid'.
2) "Error 2 The tag 'DataGrid.CellStyle' does not exist in XML namespace 'schemas.microsoft.com/winfx/2006/xaml/presentation'."
To ignore the DataGridCell (focus the content) use:
<DataGrid.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="IsTabStop" Value="False" />
<Setter Property="Focusable" Value="False" />
</Style>
</DataGrid.CellStyle>
To enter EditMode in an ElementStyle/EditingElementStyle or CellTemplate/CellEditingTemplate environment set DataGridCell.IsEditing Property to true if selected:
<Style x:Key="RightAlignedCell" TargetType="{x:Type DataGridCell}">
...
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="IsEditing" Value="True" />
...
</Trigger>
</Style.Triggers>
</Style>

Style expander buttons of TreeView

Here is my XAML:
<Style x:Key="ExpanderStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="IsEnabled" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Image Source="/Images/SHCalendarLeftArrow.tiff" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
So what I want is so that if the item is expanded, then display a different image.
Nevermind. I used a trigger
<Trigger Property="ToggleButton.IsChecked" Value="False">
<Setter x:Name="Expander_Expanded"
TargetName="Expander_Normal" Property="Source"
Value="/Images/SHCalendarLeftArrow.tiff" />
</Trigger>

Resources