Changing a Button's Background in WPF C# [duplicate] - c#

I want to change the background color of a button when IsMouseOver == True
<Button Command="{Binding ClickRectangleColorCommand}" Background="{Binding Color, Converter={StaticResource RGBCtoBrushColorsConverter},Mode=TwoWay}" Width="auto" Height="40">
<TextBlock Foreground="Black" Text="{Binding Color, Converter={StaticResource RGBCColorToTextConveter},Mode=TwoWay}"/>
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="DarkGoldenrod"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
I can't seem to understand why this trigger isn't working.

Try this- In this example Original color is green and mouseover color will be DarkGoldenrod
<Button Content="Button" HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="50" Height="50" HorizontalContentAlignment="Left" BorderBrush="{x:Null}" Foreground="{x:Null}" Margin="50,0,0,0">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Green"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="DarkGoldenrod"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>

<Button Content="Click" Width="200" Height="50">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="LightBlue" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="Border" Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="LightGreen" TargetName="Border" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Style>

As others already said, there seems to be no good solution to do that easily.
But to keep your code clean I suggest creating a seperate class that hides the ugly XAML.
How to use after we created the ButtonEx-class:
<Window x:Class="MyApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:wpfEx="clr-namespace:WpfExtensions"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<wpfEx:ButtonEx HoverBackground="Red"></wpfEx:ButtonEx>
</Grid>
</Window>
ButtonEx.xaml.cs
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace WpfExtensions
{
/// <summary>
/// Standard button with extensions
/// </summary>
public partial class ButtonEx : Button
{
readonly static Brush DefaultHoverBackgroundValue = new BrushConverter().ConvertFromString("#FFBEE6FD") as Brush;
public ButtonEx()
{
InitializeComponent();
}
public Brush HoverBackground
{
get { return (Brush)GetValue(HoverBackgroundProperty); }
set { SetValue(HoverBackgroundProperty, value); }
}
public static readonly DependencyProperty HoverBackgroundProperty = DependencyProperty.Register(
"HoverBackground", typeof(Brush), typeof(ButtonEx), new PropertyMetadata(DefaultHoverBackgroundValue));
}
}
ButtonEx.xaml
Note: This contains all the original XAML from System.Windows.Controls.Button
<Button x:Class="WpfExtensions.ButtonEx"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
x:Name="buttonExtension">
<Button.Resources>
<Style x:Key="FocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="10" StrokeDashArray="1 2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD"/>
<SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070"/>
<SolidColorBrush x:Key="Button.MouseOver.Background" Color="#FFBEE6FD"/>
<SolidColorBrush x:Key="Button.MouseOver.Border" Color="#FF3C7FB1"/>
<SolidColorBrush x:Key="Button.Pressed.Background" Color="#FFC4E5F6"/>
<SolidColorBrush x:Key="Button.Pressed.Border" Color="#FF2C628B"/>
<SolidColorBrush x:Key="Button.Disabled.Background" Color="#FFF4F4F4"/>
<SolidColorBrush x:Key="Button.Disabled.Border" Color="#FFADB2B5"/>
<SolidColorBrush x:Key="Button.Disabled.Foreground" Color="#FF838383"/>
</Button.Resources>
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
<Setter Property="Background" Value="{StaticResource Button.Static.Background}"/>
<Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsDefaulted" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="border" Value="{Binding Path=HoverBackground, ElementName=buttonExtension}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Pressed.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border}"/>
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
</Button>
Tip:
You can add an UserControl with name "ButtonEx" to your project in VS Studio and then copy paste the stuff above in.

Adding on Microsoft_DN answer, if anyone wants to reuse the style for different buttons with different color we can create a custom Button class with hovercolor and bgcolor DependencyProperty.
HoverButton.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace StackOverflow
{
public class HoverButton : Button
{
public static readonly DependencyProperty hoverColorProperty = DependencyProperty.Register
(
"hoverColor",
typeof(SolidColorBrush),
typeof(HoverButton),
new PropertyMetadata(new BrushConverter().ConvertFrom("#5D5D5D"))
);
public SolidColorBrush hoverColor
{
get { return (SolidColorBrush)GetValue(hoverColorProperty); }
set { SetValue(hoverColorProperty, value); }
}
public static readonly DependencyProperty bgColorProperty = DependencyProperty.Register
(
"bgColor",
typeof(SolidColorBrush),
typeof(HoverButton),
new PropertyMetadata(new SolidColorBrush(Colors.Red))
);
public SolidColorBrush bgColor
{
get { return (SolidColorBrush)GetValue(bgColorProperty); }
set { SetValue(bgColorProperty, value); }
}
}
}
Then add the following style in App.xaml file inside Application.Resources tag
<Style TargetType="{x:Type StackOverflow:HoverButton}" x:Key="customButton">
<Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Self}, Path = bgColor}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" Margin="{TemplateBinding Padding}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value ="{Binding RelativeSource={RelativeSource Self}, Path = hoverColor}" />
</Trigger>
</Style.Triggers>
</Style>
The we can use the style as in HoverButton
<myApp:HoverButton Height="20" Width="20" Style="{StaticResource customButton}" bgColor="Orange" hoverColor="Blue">
</myApp:HoverButton>
Because HoverButton is not using the project namespace we need to add
xmlns:myApp = "clr-namespace:StackOverflow"
in both Application tag in app.xaml and Window tag in MainWindow.xaml file.
Sample: https://github.com/ayush1920/Stackoverflow/tree/main/WPF%20HoverButton

<Button Background="#FF4148" BorderThickness="0" BorderBrush="Transparent">
<Border HorizontalAlignment="Right" BorderBrush="#FF6A6A" BorderThickness="0>
<Border.Style>
<Style TargetType="Border">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#FF6A6A" />
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
<StackPanel Orientation="Horizontal">
<Image RenderOptions.BitmapScalingMode="HighQuality" Source="//ImageName.png" />
</StackPanel>
</Border>
</Button>

Related

How to disable a button and change it's color?

I have this code I found on here, that generates me a grid of buttons - I know this may not be the best way to do this, but for now I'd like to do it this way, I am quite new at this. So the button should be either Black(1) or White(0), depending on it's value. This all works, until I hover the button and I can see it's value. If I just add the Visibility property = "false" to the button, it does not even get displayed.
This is my code:
<Window.Resources>
<DataTemplate x:Key="DataTemplate_Level2">
<Button Content="{Binding}" Height="15" Width="15" Margin="1,1,1,1">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<DataTrigger Binding="{Binding}" Value="1">
<Setter Property="Background" Value="Black"/>
<Setter Property="Foreground" Value="Black" />
</DataTrigger>
<DataTrigger Binding="{Binding}" Value="0">
<Setter Property="Background" Value="White"/>
<Setter Property="Foreground" Value="White" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</DataTemplate>
<DataTemplate x:Key="DataTemplate_Level1">
<ItemsControl ItemsSource="{Binding}" ItemTemplate="{DynamicResource DataTemplate_Level2}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</DataTemplate>
</Window.Resources>
And then I display the grid here:
<Grid Margin="10,10,10,-636" Grid.Row="3">
<ItemsControl x:Name="automata" ItemTemplate="{DynamicResource DataTemplate_Level1}" Margin="0,0,0,-119"/>
</Grid>
I would also be happy of a recommendation on how to display these values in another way.
If you want to change the appearance or visual states of a control, create a style with a ControlTemplate that fits your requirements. You can also extract the default style using Blen or Visual Studio and adapt it.
In the following, I took the default style with its control template for Button and commented out the triggers for MouseOver, Pressed and other states so they are ineffective, but you still see where to continue since your question certainly is only the starting point for further customization. I adapted and added your triggers to the ControlTemplate. What this does is simply show a black button for 1 and white for 0.
<Style x:Key="MyButtonStyle" TargetType="{x:Type Button}">
<Style.Resources>
<SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD"/>
<SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070"/>
<SolidColorBrush x:Key="Button.MouseOver.Background" Color="#FFBEE6FD"/>
<SolidColorBrush x:Key="Button.MouseOver.Border" Color="#FF3C7FB1"/>
<SolidColorBrush x:Key="Button.Pressed.Background" Color="#FFC4E5F6"/>
<SolidColorBrush x:Key="Button.Pressed.Border" Color="#FF2C628B"/>
<SolidColorBrush x:Key="Button.Disabled.Background" Color="#FFF4F4F4"/>
<SolidColorBrush x:Key="Button.Disabled.Border" Color="#FFADB2B5"/>
<SolidColorBrush x:Key="Button.Disabled.Foreground" Color="#FF838383"/>
</Style.Resources>
<Setter Property="FocusVisualStyle">
<Setter.Value>
<Style>
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" StrokeDashArray="1 2" SnapsToDevicePixels="true" StrokeThickness="1" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
<Setter Property="Background" Value="{StaticResource Button.Static.Background}"/>
<Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" SnapsToDevicePixels="true">
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<!-- These are the default triggers, which you might customize to fit your style. -->
<!--<Trigger Property="IsDefaulted" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.MouseOver.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Pressed.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border}"/>
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/>
</Trigger>-->
<!-- These are your triggers, which now act on the Content property of the templated button. -->
<DataTrigger Binding="{Binding Content, RelativeSource={RelativeSource TemplatedParent}}" Value="1">
<Setter Property="Background" Value="Black"/>
<Setter Property="Foreground" Value="Black" />
</DataTrigger>
<DataTrigger Binding="{Binding Content, RelativeSource={RelativeSource TemplatedParent}}" Value="0">
<Setter Property="Background" Value="White"/>
<Setter Property="Foreground" Value="White" />
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Use this style in your data template and you should get the expected result.
<DataTemplate x:Key="DataTemplate_Level2">
<Button Content="{Binding}" Height="15" Width="15" Margin="1,1,1,1" Style="{DynamicResource MyButtonStyle}"/>
</DataTemplate>
Since you try to make the text 1 and 0 invisible by setting the background and foreground to the same color, you could also simply remove the ContentPresenter from the ControlTemplate, so there is no content displayed at all and the Foreground setters are not needed.
Another thing to note is that your binary state maybe suggests to use a ToggleButton instead.
Base class for controls that can switch states, such as CheckBox.
This is an example style for a ToggleButton that does not show content and sets the background like in your question, but dependening on its IsChecked property.
<Style x:Key="MyToggleButtonStyle" TargetType="{x:Type ToggleButton}">
<Style.Resources>
<SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD"/>
<SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070"/>
</Style.Resources>
<Setter Property="FocusVisualStyle">
<Setter.Value>
<Style>
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" StrokeDashArray="1 2" SnapsToDevicePixels="true" StrokeThickness="1" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
<Setter Property="Background" Value="{StaticResource Button.Static.Background}"/>
<Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border x:Name="border" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" SnapsToDevicePixels="true"/>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Background" Value="Black"/>
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Background" Value="White"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Change the binding in your data template from Content to IsChecked.
<DataTemplate x:Key="DataTemplate_Level2">
<ToggleButton IsChecked="{Binding}" Height="15" Width="15" Margin="1,1,1,1" Style="{DynamicResource MyToggleButtonStyle}"/>
</DataTemplate>
This buys you the advantage of toggling the states automatically, but only if you can provide a property for two-way binding (getter and setter), otherwise an exception will be thrown.

No Row selected when clicked on WPF DatagridRow Border

I design a Datagrid based on Style set for DataGrid, DataGridRow and DataGridCell. I have set border between rows using DatagridRow Style and DGR_Border(as in code). When I click on a row it gets selected, but when I click on row borders, no row is selected, nothing happens when clicked on these borders. I want to click row and select it without forcing me to re-click just because I accidentally clicked in between the rows. Since these borders are part of DatagridRow itself, they are associated with some row and must respond to clicks or hittest? I ended up implementing a MouseDown event on Datagrid and identify the parent of the dependency object to be DatagridRow and get and set the index. This will work perfectly for Single Selection Mode but I will end up implementing the logics for Extended case, if mouse clicked with Keybaord modifiers Control and Shift. I feel there is something simple hidden in XAML which can be set to fix this issue. Hope someone's eye will catch what I am missing. Please find below the sample with exact issue:
MainWindow.xaml
<Window x:Class="WpfApp3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800"
x:Name="this" >
<Window.Resources>
<ResourceDictionary>
<Style x:Key="DataGridStyle" TargetType="DataGrid">
<Setter Property="Background" Value="DarkGray"/>
<Setter Property="Foreground" Value="Blue"/>
<Setter Property="BorderBrush" Value="{x:Null}"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="CanUserResizeColumns" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DataGrid">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="True">
<ScrollViewer x:Name="DG_ScrollViewer" PanningMode="Both" >
<ScrollViewer.Template>
<ControlTemplate TargetType="ScrollViewer">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<DataGridColumnHeadersPresenter x:Name="PART_ColumnHeadersPresenter" Grid.Column="1" Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.Column}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter"
CanContentScroll="{TemplateBinding CanContentScroll}"
Grid.ColumnSpan="2" Grid.Row="1"/>
<ScrollBar x:Name="PART_VerticalScrollBar"
Grid.Row="1" Grid.Column="2"
MinWidth="40"
Value="{TemplateBinding VerticalOffset}"
Maximum="{TemplateBinding ScrollableHeight}"
ViewportSize="{TemplateBinding ViewportHeight}"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"
Panel.ZIndex="5"
ClipToBounds="False"/>
<ScrollBar x:Name="PART_HorizontalScrollBar"
Orientation="Horizontal"
Grid.Row="2"
Grid.Column="1"
Value="{TemplateBinding HorizontalOffset}"
Maximum="{TemplateBinding ScrollableWidth}"
ViewportSize="{TemplateBinding ViewportWidth}"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/>
</Grid>
</ControlTemplate>
</ScrollViewer.Template>
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="VerticalScrollBarVisibility" Value="Hidden">
<Setter TargetName="DG_ScrollViewer" Property="VerticalScrollBarVisibility" Value="Hidden"/>
</Trigger>
<Trigger Property="VerticalScrollBarVisibility" Value="Disabled">
<Setter TargetName="DG_ScrollViewer" Property="VerticalScrollBarVisibility" Value="Disabled"/>
</Trigger>
<Trigger Property="HorizontalScrollBarVisibility" Value="Hidden">
<Setter TargetName="DG_ScrollViewer" Property="HorizontalScrollBarVisibility" Value="Hidden"/>
</Trigger>
<Trigger Property="HorizontalScrollBarVisibility" Value="Disabled">
<Setter TargetName="DG_ScrollViewer" Property="HorizontalScrollBarVisibility" Value="Disabled"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="GridLinesVisibility" Value="None"/>
<Setter Property="ColumnWidth" Value="*"/>
<Setter Property="IsReadOnly" Value="True"/>
<Setter Property="HorizontalScrollBarVisibility" Value="Disabled"/>
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsGrouping" Value="true"/>
<Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</MultiTrigger>
</Style.Triggers>
</Style>
<Style x:Key="DataGridRowStyle" TargetType="{x:Type DataGridRow}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="Validation.ErrorTemplate" Value="{x:Null}"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="ValidationErrorTemplate">
<Setter.Value>
<ControlTemplate>
<TextBlock Foreground="Red" Margin="2,0,0,0" Text="!" VerticalAlignment="Center"/>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridRow}">
<!--BorderBrush="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Tag, Converter={StaticResource RandomColorBrushGeneratorConverter}}"-->
<Border x:Name="DGR_Border"
IsHitTestVisible="True"
BorderThickness="0,3,0,3"
BorderBrush="Black"
Background="{TemplateBinding Background}"
SnapsToDevicePixels="True"
CornerRadius="4,4,4,4"
Opacity="1"
RenderTransformOrigin="0.5,0.5">
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Border.RenderTransform>
<SelectiveScrollingGrid>
<SelectiveScrollingGrid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</SelectiveScrollingGrid.ColumnDefinitions>
<SelectiveScrollingGrid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</SelectiveScrollingGrid.RowDefinitions>
<DataGridCellsPresenter Grid.Column="1" ItemsPanel="{TemplateBinding ItemsPanel}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
<DataGridDetailsPresenter Grid.Column="1" Grid.Row="1" SelectiveScrollingGrid.SelectiveScrollingOrientation="{Binding AreRowDetailsFrozen, ConverterParameter={x:Static SelectiveScrollingOrientation.Vertical}, Converter={x:Static DataGrid.RowDetailsScrollingConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" Visibility="{TemplateBinding DetailsVisibility}"/>
</SelectiveScrollingGrid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Margin" Value="0,0,0,0"/>
<Setter Property="Background" Value="Gray"/>
<Setter Property="Opacity" Value="1"/>
<Style.Triggers>
<Trigger Property="IsNewItem" Value="True">
<Setter Property="Margin" Value="{Binding NewItemMargin, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="DataGridCellStyle" TargetType="{x:Type DataGridCell}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="FontSize" Value="16"/>
<Setter Property="Padding" Value="12"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Border
IsHitTestVisible="True"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
SnapsToDevicePixels="True">
<Grid Background="Transparent" IsHitTestVisible="True">
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
Margin="{TemplateBinding Padding}"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="LightGray"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="Black"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{StaticResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
</Window.Resources>
<Grid>
<DataGrid
x:Name="_mainDataGrid"
ItemsSource="{Binding ElementName=this, Path=Dummies}"
Style="{StaticResource DataGridStyle}"
CellStyle="{StaticResource DataGridCellStyle}"
RowStyle="{StaticResource DataGridRowStyle}"
SelectionMode="Extended"
PreviewMouseDown="DataGrid_PreviewMouseDown"/>
</Grid>
MainWindow.xaml.cs
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace WpfApp3
{
public class Dummy
{
public Dummy(string f, string l, string a)
{
FirstName = f;
LastName = l;
Address = a;
}
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
}
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
Dummies = new ObservableCollection<Dummy>();
for(int i = 0; i < 10; i++)
{
Dummy dummy = new Dummy("F" + i.ToString(), "L" + i.ToString(), "ADDRESS: " + i.ToString());
Dummies.Add(dummy);
}
InitializeComponent();
}
public ObservableCollection<Dummy> Dummies { get; }
public static T GetParentOfType<T>(DependencyObject current)
where T : DependencyObject
{
for (DependencyObject parent = VisualTreeHelper.GetParent(current);
parent != null;
parent = VisualTreeHelper.GetParent(parent))
{
if (parent is T result)
return result;
}
return null;
}
/// <summary>
/// Want to Avoid this and have something in XAML
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void DataGrid_PreviewMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
//Will end up implementing logic for Multiselection using Control and shift modifiers
if (e.OriginalSource is DependencyObject dep &&
GetParentOfType<DataGridRow>(dep) is DataGridRow dataGridRow)
{
_mainDataGrid.SelectedIndex = dataGridRow.GetIndex();
}
}
}
}
Note:: I have already tried the solution mentioned here DataGrid row selection not working when padding is added to cells as seen in my code above and it didn't help.
Since I was not able to find a straight forward way, I did something else to fix it. In DataGridRow Style, I set my border transparent and enable it on row selection and Draw Bottom Border for each cell in DataGridCell Style which replicates DataGrid Row Border amd disable it on row selection.
DataGridRow Style Change:
<Border x:Name="DGR_Border"
IsHitTestVisible="True"
BorderThickness="0"
BorderBrush="Transparent"
Background="{TemplateBinding Background}"
SnapsToDevicePixels="True"
CornerRadius="4,4,4,4"
Opacity="1"
RenderTransformOrigin="0.5,0.5">
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="DGR_Border" Property="BorderThickness" Value="0,0,0,6"/>
<Setter TargetName="DGR_Border" Property="BorderBrush" Value="Black"/>
</Trigger>
</ControlTemplate.Triggers>
DataGridCell Style Change:
<Style x:Key="DataGridCellStyle" TargetType="{x:Type DataGridCell}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="BorderThickness" Value="0,0,0,6"/>
<Setter Property="FontSize" Value="16"/>
<Setter Property="Padding" Value="12"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="Black"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="BorderBrush" Value="Transparent"/>
</Trigger>
</Style.Triggers>

Trigger not working on custom control image button wpf

I have created one custom cotrol
Generic.xaml code is below -
<BitmapImage x:Key="RightImaGE" x:Name="imgD" UriSource="/XYZ.UI_Test;components/Resources/Pfad55-1.png"/>
<Style TargetType="{x:Type local1:CustomButton}" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local1:CustomButton}">
<!--<Image Name="imgDefault" Source="{TemplateBinding Image}" Stretch="UniformToFill" />-->
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding Path=ContentOff, RelativeSource={RelativeSource AncestorType=local1:CustomButton}}" Value="SETTINGS">
<Setter Property="Background" Value="Red"/>
<Setter Property="Image.Source" Value="{DynamicResource RightImaGE}" />
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
CustomButton.cs codebehind is below
public string ContentOff
{
get { return (string)GetValue(ContentOffProperty); }
set { SetValue(ContentOffProperty, value); }
}
public static readonly DependencyProperty ContentOffProperty =
DependencyProperty.Register("ContentOff",
typeof(string), typeof(CustomButton), new PropertyMetadata(null));
public ImageSource Image
{
get { return (ImageSource)GetValue(ImageProperty); }
set { SetValue(ImageProperty, value); }
}
public static readonly DependencyProperty ImageProperty =
DependencyProperty.Register("Image", typeof(ImageSource), typeof(CustomButton), new PropertyMetadata(default(ImageSource)));
I have defined one common style in app.xaml code is below
<Application.Resources>
<Style x:Key="BigButtonStyle" TargetType="local:CustomButton" >
<Setter Property="Control.Background" Value="Transparent"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="Margin" Value="1"/>
<Setter Property="FontSize" Value="27"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Foreground" Value="#1d5560"/>
<Setter Property="Width" Value="170"/>
<Setter Property="MaxHeight" Value="50"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:CustomButton}">
<Canvas Margin="1">
<Image x:Name="img" Source="Resources/Pfad55.png" Stretch="UniformToFill" >
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="Resources/Pfad55.png" />
<!--<Style.Triggers>
--><!--<Trigger Property="ContentOff" Value="SETTINGS">
<Setter Property="Opacity" Value="0.5" />
</Trigger>--><!--
</Style.Triggers>-->
</Style>
</Image.Style>
</Image>
<ContentPresenter HorizontalAlignment="Center" Content="{TemplateBinding ContentOff}" Canvas.Top="14" Canvas.Left="47"
VerticalAlignment="Center"/>
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Now I have Mainwindows.xaml where I am using Custombutton and if button content is Settings it should change different image through trigger than common image which is defined in bigbuttonstyle .
<Controls:CustomButton Grid.Row="8" Grid.Column="2" Style="{StaticResource BigButtonStyle}"
ContentOff="SETTINGS"
Image="Resources/Pfad55-1.png"/>
I tried to use data trigger here but not working and tried property trigger too. But image not changing somehow.
You can use two different style with style inheritance -
<Style x:Key="SmallButtonStyle" TargetType="local:CustomButton" BasedOn="{StaticResource BigButtonStyle}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:CustomButton}">
<Canvas Margin="1">
<Image Source="Resources/Pfad55-1.png" Stretch="UniformToFill" ></Image>
<ContentPresenter HorizontalAlignment="Center" Content="{TemplateBinding ContentOff}" Canvas.Top="14" Canvas.Left="85"
VerticalAlignment="Center"/>
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
then use it
<Controls:CustomButton Grid.Row="8" Grid.Column="2" Style="{StaticResource SmallButtonStyle}"
ContentOff="SETTINGS"
Image="Resources/Pfad55-1.png"/>
It'll be working but without trigger.
Another solution I have added based on your requirement.
Change your Generic.Xaml code like below.
<Style TargetType="{x:Type local1:CustomButton}" >
<Setter Property="FontSize" Value="27"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Foreground" Value="#1d5560"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local1:CustomButton}">
<Grid>
<Image Stretch="Fill" >
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="Resources/Pfad55.png" />
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local1:CustomButton},Path=ContentOff}"
Value="SETTINGS">
<Setter Property="Source"
Value="Resources/Pfad55-1.png" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
<ContentPresenter HorizontalAlignment="Left" Margin="50,0,0,0" Content="{TemplateBinding ContentOff}"
VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And Chnage your MainWindow.xaml implementation with this
<Controls:CustomButton Grid.Row="8" Grid.Column="2" ContentOff="SETTINGS"/>
You were using App.xaml style with BigButtonStyle , that's why custom control styles and trigger was not firing. Your App.xaml style was locally overriding custom control style and trigger from Generic.xaml.

Change button property when IsEnabled change in wpf

I have a button in my view with style in staticResource. I have IsEnabled bind to a bool in my viewmodel and want to change background when is disable.
I tried to use Style.Triggers on IsEnabled = false but this don't change the background.
Styles.xaml
<Style x:Key="buttonNegative" TargetType="Button">
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="Green"/>
</Trigger>
</Style.Triggers>
</Style>
view.xaml
<Button Style="{StaticResource buttonNegative}" Command="{Binding InversionAxis_Command}" IsEnabled="{Binding SettingsButtonIsEnable}">
<TextBlock Text="{Binding Orientation}"/>
</Button>
viewModel.cs
private bool _settingsButtonIsEnable;
public bool SettingsButtonIsEnable
{
get { return _settingsButtonIsEnable; }
set
{
if (Equals(value, _settingsButtonIsEnable)) return;
_settingsButtonIsEnable = value;
RaisePropertyChanged();
}
}
public ICommand InversionAxis_Command
{
get { return new RelayCommand(InversionAxis, IsSettingsButtonIsEnable); }
}
private bool IsSettingsButtonIsEnable()
{
return _settingsButtonIsEnable;
}
The command was not execute because I use canExecute but the style not changing when SettingsButtonIsEnable change
It's more complicated to change the disabled background than adding a trigger to the style. You'll have to define a custom ControlTemplate:
<Style x:Key="buttonNegative" TargetType="Button">
<Style.Resources>
<Style x:Key="FocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD"/>
<SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070"/>
<SolidColorBrush x:Key="Button.MouseOver.Background" Color="#FFBEE6FD"/>
<SolidColorBrush x:Key="Button.MouseOver.Border" Color="#FF3C7FB1"/>
<SolidColorBrush x:Key="Button.Pressed.Background" Color="#FFC4E5F6"/>
<SolidColorBrush x:Key="Button.Pressed.Border" Color="#FF2C628B"/>
<SolidColorBrush x:Key="Button.Disabled.Background" Color="Green"/>
<SolidColorBrush x:Key="Button.Disabled.Border" Color="#FFADB2B5"/>
<SolidColorBrush x:Key="Button.Disabled.Foreground" Color="#FF838383"/>
</Style.Resources>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsDefaulted" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.MouseOver.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Pressed.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border}"/>
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The default disabled background is hardcoded into the default template and cannot be overridden with a style setter.

WPF TreeView with right alignment values issue

I am trying to make a TreeView with items that have some counts etc. right aligned when shown. I came across the following on SO, but I can't figure out why my output is not actually a TreeView, there are not arrows (expanders or whatever) and no indentation etc, like the image shows it is. There are some things left out in the description of the solution. Apparently they used a List of 'MyTreeItem'. but I don't see how that would create any hierarchical relationship. So i just get a list basically, albeit with the properties shown how i want.
Here's my XAML:
<Window x:Class="TreeView.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:m="clr-namespace:TreeView"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.Resources>
<Style x:Key="TreeViewItemFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<PathGeometry x:Key="TreeArrow" Figures="M0,0 L0,6 L6,0 z"/>
<Style x:Key="ExpandCollapseToggleStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="Focusable" Value="False"/>
<Setter Property="Width" Value="16"/>
<Setter Property="Height" Value="16"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Background="Transparent" Height="16" Padding="5,5,5,5" Width="16">
<Path x:Name="ExpandPath" Data="{StaticResource TreeArrow}" Fill="Transparent" Stroke="#FF989898">
<Path.RenderTransform>
<RotateTransform Angle="135" CenterY="3" CenterX="3"/>
</Path.RenderTransform>
</Path>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Stroke" TargetName="ExpandPath" Value="#FF1BBBFA"/>
<Setter Property="Fill" TargetName="ExpandPath" Value="Transparent"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="RenderTransform" TargetName="ExpandPath">
<Setter.Value>
<RotateTransform Angle="180" CenterY="3" CenterX="3"/>
</Setter.Value>
</Setter>
<Setter Property="Fill" TargetName="ExpandPath" Value="#FF595959"/>
<Setter Property="Stroke" TargetName="ExpandPath" Value="#FF262626"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="StretchTreeViewItemStyle"
TargetType="{x:Type TreeViewItem}"
xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="Padding" Value="1,0,0,0"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="FocusVisualStyle" Value="{StaticResource TreeViewItemFocusVisual}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeViewItem}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="19" Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<ToggleButton x:Name="Expander" ClickMode="Press" IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource TemplatedParent}}" Style="{StaticResource ExpandCollapseToggleStyle}"/>
<Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.Column="1" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
<ContentPresenter x:Name="PART_Header" ContentSource="Header" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
<ItemsPresenter x:Name="ItemsHost" Grid.Column="1" Grid.Row="1"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="false">
<Setter Property="Visibility" TargetName="ItemsHost" Value="Collapsed"/>
</Trigger>
<Trigger Property="HasItems" Value="false">
<Setter Property="Visibility" TargetName="Expander" Value="Hidden"/>
</Trigger>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="VirtualizingStackPanel.IsVirtualizing" Value="true">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<TreeView ItemsSource="{Binding Path=Items}"
Grid.RowSpan="2"
Grid.ColumnSpan="2"
ItemContainerStyle="{StaticResource StretchTreeViewItemStyle}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type m:MyTreeItem}" ItemsSource="{Binding Items}">
<DockPanel LastChildFill="True">
<TextBlock Text="{Binding Path=Value}" DockPanel.Dock="Right"/>
<TextBlock Text="{Binding Path=Display}" DockPanel.Dock="Left"/>
</DockPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Grid>
Here's the code=behind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace TreeView
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
Items = new List<MyTreeItem>();
MyTreeItem one = new MyTreeItem();
one.Display = "Level 1";
one.Value = "Level1";
Items.Add(one);
MyTreeItem two = new MyTreeItem();
two.Display = "Volvo";
two.Value = "Volvo";
Items.Add(two);
MyTreeItem three = new MyTreeItem();
three.Display = "New";
three.Value = "New";
Items.Add(three);
MyTreeItem four = new MyTreeItem();
four.Display = "Old";
four.Value = "Old";
Items.Add(four);
}
public List<MyTreeItem> Items
{ get; set; }
}
public class MyTreeItem
{
public string Display
{ get; set; }
public string Value
{ get;set; }
}
}
And here's image of how its supposed to look according to the post:
But this is what I get:
How do i fix this? What am i missing here?
duh i forgot to actually add the children, so i just had to make List Items inside the class so now it's recursive

Categories