How do I make a CheckBox look like a RadioButton - wpf

I wanna use a CheckBox but I want it to have the RadioButton chrome.
What's the easiest way to do this?

public partial class RadioCheckBox : CheckBox
{...}
RadioCheckBox.xaml:
<CheckBox
x:Class="WpfApplication1.RadioCheckBox"
...
xmlns:m="clr-namespace:WpfApplication1"
>
<CheckBox.Style>
<Style TargetType="{x:Type m:RadioCheckBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type m:RadioCheckBox}">
<Grid>
<RadioButton
IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent},
Path=IsChecked, Mode=TwoWay}"
IsHitTestVisible="False" />
<CheckBox
IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent},
Path=IsChecked, Mode=TwoWay}" Opacity="0"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</CheckBox.Style>

This actually works just like I desired:
<Style TargetType="{x:Type CheckBox}" x:Key="CheckBox_RadioButtonStyle">
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="Background" Value="#F4F4F4"/>
<Setter Property="BorderBrush" Value="#8E8F8F"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="FocusVisualStyle">
<Setter.Value>
<Style>
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="1" SnapsToDevicePixels="True"
Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"
StrokeThickness="1" StrokeDashArray="1 2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<BulletDecorator Background="Transparent" SnapsToDevicePixels="true">
<BulletDecorator.Bullet>
<themes:BulletChrome BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}"
IsChecked="{TemplateBinding IsChecked}"
RenderMouseOver="{TemplateBinding IsMouseOver}"
RenderPressed="{TemplateBinding IsPressed}" IsRound="True"/>
</BulletDecorator.Bullet>
<ContentPresenter
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}" RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</BulletDecorator>
<ControlTemplate.Triggers>
<Trigger Property="HasContent" Value="true">
<Setter Property="FocusVisualStyle"
Value="{StaticResource CheckRadioFocusVisual}"/>
<Setter Property="Padding" Value="4,0,0,0"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-------------------------------------->
<DataGridCheckBoxColumn x:Name="colSelected" Header="Selected"
ElementStyle="{StaticResource CheckBox_RadioButtonStyle}"/>

XAML:
<DataGrid x:Name="dg">
<DataGrid.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock Text="Test"/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</DataGrid.GroupStyle>
<DataGrid.Resources>
<Style x:Key="myStyle" TargetType="CheckBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CheckBox">
<RadioButton IsChecked="{Binding IsChecked, Mode=TwoWay, RelativeSource={RelativeSource AncestorType=CheckBox}}"
Content="{TemplateBinding Content}"
GroupName="{Binding MyProperty}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridCheckBoxColumn ElementStyle="{StaticResource myStyle}"
EditingElementStyle="{StaticResource myStyle}"
IsReadOnly="False"
Binding="{Binding Flag, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Header="1"/>
</DataGrid.Columns>
</DataGrid>
Code-Behind:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
object[] items = new object[] {
new MyClass() { Flag = false, MyProperty = 1 },
new MyClass() { Flag = false, MyProperty = 1 },
new MyClass() { Flag = false, MyProperty = 1 },
new MyClass() { Flag = false, MyProperty = 1 },
new MyClass() { Flag = false, MyProperty = 1 },
new MyClass() { Flag = false, MyProperty = 2 },
new MyClass() { Flag = true, MyProperty = 2 },
new MyClass() { Flag = false, MyProperty = 2 },
};
ICollectionView cv = CollectionViewSource.GetDefaultView(items);
cv.GroupDescriptions.Add(new PropertyGroupDescription("MyProperty"));
this.dg.ItemsSource = cv;
}
public class MyClass : INotifyPropertyChanged
{
public int MyProperty { get; set; }
private bool flag;
public bool Flag
{
get { return this.flag; }
set
{
this.flag = value;
this.OnPropertyChanged("Flag");
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
#endregion
}
}

just try this..
<SolidColorBrush x:Key="CheckBoxStroke" Color="#8E8F8F"/>
<Style x:Key="CheckRadioFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Stroke="Black" StrokeDashArray="1 2" StrokeThickness="1" Margin="14,0,0,0" SnapsToDevicePixels="true"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="CheckBoxStyle1" TargetType="{x:Type CheckBox}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="Background" Value="{StaticResource CheckBoxFillNormal}"/>
<Setter Property="BorderBrush" Value="{StaticResource CheckBoxStroke}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="FocusVisualStyle" Value="{StaticResource EmptyCheckBoxFocusVisual}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<BulletDecorator SnapsToDevicePixels="true" Background="Transparent">
<BulletDecorator.Bullet>
<Microsoft_Windows_Themes:BulletChrome Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" IsChecked="{TemplateBinding IsChecked}" RenderMouseOver="{TemplateBinding IsMouseOver}" IsRound="True" RenderPressed="{TemplateBinding IsPressed}"/>
</BulletDecorator.Bullet>
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" RecognizesAccessKey="True"/>
</BulletDecorator>
<ControlTemplate.Triggers>
<Trigger Property="HasContent" Value="true">
<Setter Property="FocusVisualStyle" Value="{StaticResource CheckRadioFocusVisual}"/>
<Setter Property="Padding" Value="4,0,0,0"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<CheckBox HorizontalAlignment="Left" Margin="186,31,0,0" Style="{DynamicResource CheckBoxStyle1}" VerticalAlignment="Top" Content="CheckBox"/>
<CheckBox Margin="310,31,246.58,0" Style="{DynamicResource CheckBoxStyle1}" VerticalAlignment="Top" Content="CheckBox" d:LayoutOverrides="Width"/>
<CheckBox HorizontalAlignment="Right" Margin="0,31,150.58,0" Style="{DynamicResource CheckBoxStyle1}" VerticalAlignment="Top" Content="CheckBox"/>

Related

WPF apply style only in particular conditions

I had to adapt the visual stye of my combobox due to migration from Win7 to Win10, so here's my current style for custom Combobox:
<Style TargetType="{x:Type av:XComboBox}">
<Setter Property="UIElement.SnapsToDevicePixels" Value="True"/>
<Setter Property="FrameworkElement.OverridesDefaultStyle" Value="True"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
<Setter Property="TextElement.Foreground" Value="Black"/>
<Setter Property="FrameworkElement.FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Grid>
<ToggleButton Name="ToggleButton" Grid.Column="2"
ClickMode="Press" Focusable="False"
IsChecked="{Binding Path=IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
Template="{StaticResource ComboBoxToggleButtonTemplate}"/>
<ContentPresenter Name="ContentSite" Margin="5, 3, 23, 3" IsHitTestVisible="False"
HorizontalAlignment="Left" VerticalAlignment="Center"
Content="{TemplateBinding ComboBox.SelectionBoxItem}"
ContentTemplate="{TemplateBinding ComboBox.SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"/>
<TextBox Name="PART_EditableTextBox" Margin="1, 3, 23, 3" IsReadOnly="{TemplateBinding IsReadOnly}" Visibility="Hidden" Background="Transparent" HorizontalAlignment="Left" VerticalAlignment="Center" Focusable="True" >
<TextBox.Template>
<ControlTemplate TargetType="TextBox" >
<Border Name="PART_ContentHost" Focusable="False" />
</ControlTemplate>
</TextBox.Template>
</TextBox>
<!-- Popup showing items -->
<Popup Name="Popup" Placement="Bottom" Focusable="False" AllowsTransparency="True" IsOpen="{TemplateBinding ComboBox.IsDropDownOpen}" PopupAnimation="Slide">
<Grid Name="DropDown" SnapsToDevicePixels="True" MinWidth="{TemplateBinding FrameworkElement.ActualWidth}" MaxHeight="{TemplateBinding ComboBox.MaxDropDownHeight}">
<Border Name="DropDownBorder" Background="White" Margin="0, 1, 0, 0" CornerRadius="0" BorderThickness="1,1,1,1" BorderBrush="{StaticResource ComboBoxNormalBorderBrush}"/>
<ScrollViewer Margin="4" SnapsToDevicePixels="True">
<ItemsPresenter KeyboardNavigation.DirectionalNavigation="Contained" />
</ScrollViewer>
</Grid>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="ItemsControl.HasItems" Value="False">
<Setter Property="FrameworkElement.MinHeight" TargetName="DropDownBorder" Value="95"/>
</Trigger>
<Trigger Property="UIElement.IsEnabled" Value="False">
<Setter Property="TextElement.Foreground" Value="{StaticResource ComboBoxDisabledForegroundBrush}"/>
</Trigger>
<Trigger Property="ComboBox.IsVisible" Value="True">
<Setter Property="Border.BorderBrush" TargetName="DropDownBorder" Value="#878787"/>
</Trigger>
<Trigger Property="ItemsControl.IsGrouping" Value="True">
<Setter Property="ScrollViewer.CanContentScroll" Value="False"/>
</Trigger>
<Trigger Property="ComboBox.IsEditable" Value="True">
<Setter Property="KeyboardNavigation.IsTabStop" Value="False"/>
<Setter Property="UIElement.Visibility" TargetName="PART_EditableTextBox" Value="Visible"/>
<Setter Property="UIElement.Visibility" TargetName="ContentSite" Value="Hidden"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
As the application runs both on Win7 and Win10, I would apply that style only on Win10. Is there any way to do this? I couldn't fine anything regarding this; I thought about a converter, but how to apply it?
You could give your Style an x:Key and implement a custom markup extension:
public class Windows10StyleExtension : MarkupExtension
{
private readonly string _key;
public Windows10StyleExtension(string key)
{
_key = key;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
if (!IsWindows7OrLower)
return new StaticResourceExtension(_key).ProvideValue(serviceProvider);
return null;
}
private bool IsWindows7OrLower =>
(Environment.OSVersion.Version.Major + (double)Environment.OSVersion.Version.Minor / 10) <= 6.1;
}
XAML:
<Style x:Key="style" TargetType="{x:Type av:XComboBox}">
...
<av:XComboBox Style="{local:Windows10Style style}" />

WPF: Change Progress-Bar color according its value and View Model property

Ok so i have this property in my View Model:
public bool IsChecked
{
get { return _isChecked; }
set
{
_isChecked = value;
OnPropertyChanged(); // I also try OnPropertyChanged("IsChecked");
}
}
And as you can see this implement INotifyPropertyChanged.
When this property is changing i can see the it notify and get the correct value.
This is my Progress-Bar:
<ProgressBar Name="progressBarColumn"
Value="{Binding Progress, UpdateSourceTrigger=PropertyChanged}"
Width="{Binding Path=Width, ElementName=ProgressCell}"
Style="{StaticResource CustomProgressBar}" />
And my Progress-Bar style:
<Style x:Key="CustomProgressBar" TargetType="ProgressBar">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ProgressBar" >
<Grid x:Name="Root">
<Border Name="PART_Track"
CornerRadius="0"
Background="{DynamicResource ProgressBackgroundColor}"
BorderBrush="{DynamicResource ProgressBackgroundColor}"
BorderThickness="1" />
<Border Name="PART_Indicator"
CornerRadius="0"
Background="{DynamicResource ProgressBarFillColor}"
BorderBrush="{DynamicResource ProgressBarFillColor}"
BorderThickness="1"
HorizontalAlignment="Left" />
</Grid>
<ControlTemplate.Triggers>
<DataTrigger Value="100" Binding="{Binding Path=Value, RelativeSource={RelativeSource AncestorType=ProgressBar}}">
<Setter Property="Background" Value="Green"/>
</DataTrigger>
<DataTrigger Value="False" Binding="{Binding IsChecked}">
<Setter Property="Background" Value="Red"/>
</DataTrigger>
<Trigger Property="Orientation" Value="Vertical">
<Setter TargetName="Root" Property="LayoutTransform">
<Setter.Value>
<RotateTransform Angle="270" />
</Setter.Value>
</Setter>
<Setter TargetName="Root" Property="Width" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Height}"/>
<Setter TargetName="Root" Property="Height" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Width}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
So this is the things that currently not working:
When my Progress-Bar reach the value of 100% i want its Background color will change so i add this DataTrigger:
<DataTrigger Value="100" Binding="{Binding Path=Value, RelativeSource={RelativeSource AncestorType=ProgressBar}}">
<Setter Property="Background" Value="Green"/>
</DataTrigger>
So this not effect at all over my Pregress-Bar color when its reach 100%.
I even also try:
<DataTrigger Value="100" Binding="{Binding Path=Value, RelativeSource={RelativeSource Self}}">
<Setter Property="Background" Value="Red"/>
</DataTrigger>
When my View Model IsChecked property is set to false i want that my Progress-Bar Background color will change to Red - also this is not working.
I try to search many solutions but again and again same results - my Progress-Bar``color not changing at all.
EDIT:
<Style x:Key="CustomProgressBar2" TargetType="ProgressBar">
<Style.Triggers>
<Trigger Value="100" Property="Value">
<Setter Property="Background" Value="{DynamicResource ProgressBarFillCompleteColor}"/>
<Setter Property="Foreground" Value="Transparent"/>
</Trigger>
<DataTrigger Value="False" Binding="{Binding IsChecked}">
<Setter Property="Background" Value="Red"/>
</DataTrigger>
</Style.Triggers>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ProgressBar" >
<Grid x:Name="Root">
<Border Name="PART_Track"
CornerRadius="0"
Background="{DynamicResource ProgressBorderBrushColor}"
BorderBrush="{DynamicResource ProgressBorderBrushColor}"
BorderThickness="1" />
<Border Name="PART_Indicator"
CornerRadius="0"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding Background}"
BorderThickness="1"
HorizontalAlignment="Left" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
First of all you need properly implement INotifyPropertyChanged interface.
public event PropertyChangedEventHandler PropertyChanged;
private int _Progress;
private int _Progress;
public int Progress
{
get {
return _Progress;
}
set
{
_Progress = value;
PropertyChanged(this, new PropertyChangedEventArgs("Progress"));
}
}
Then change your style. It will be better to use Style.Triggers instead
<Style.Triggers>
<Trigger Value="100" Property="Value">
<Setter Property="Background" Value="Green"/>
<Setter Property="Foreground" Value="Pink"/>
</Trigger>
<DataTrigger Value="False" Binding="{Binding IsChecked}">
<Setter Property="Background" Value="Red"/>
</DataTrigger>
</Style.Triggers>
And modify background binding on your barders inside template
<Border Name="PART_Track"
CornerRadius="0"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding Background}"
BorderThickness="1" />
<Border Name="PART_Indicator"
CornerRadius="0"
Background="{TemplateBinding Foreground}"
BorderBrush="{TemplateBinding Foreground}"
BorderThickness="1"
HorizontalAlignment="Left" />
It will be enough to change Background when progress will be 100, but when progress will be more than 100 ( if you need it) foreground and background will be switched to default value. If you need to change color for progress >= 100 then you need ValueConverter instead of triggers.
EDIT:
Full solution.
<Window x:Class="WpfApplication3.ProgressWindow"
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:local="clr-namespace:WpfApplication3"
mc:Ignorable="d"
Title="ProgressWindow" Height="200" Width="400">
<Window.Resources>
<SolidColorBrush x:Key="ProgressBarFillCompleteColor" Color="Green"/>
<SolidColorBrush x:Key="ProgressBorderBrushColor" Color="Gray"/>
<Style x:Key="CustomProgressBar" TargetType="ProgressBar">
<Setter Property="Foreground" Value="AliceBlue"/>
<Setter Property="Background" Value="{DynamicResource ProgressBorderBrushColor}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ProgressBar" >
<Grid x:Name="Root">
<Border Name="PART_Track"
CornerRadius="0"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding Background}"
BorderThickness="1" />
<Border Name="PART_Indicator"
CornerRadius="0"
Background="{TemplateBinding Foreground}"
BorderBrush="{TemplateBinding Foreground}"
BorderThickness="1"
HorizontalAlignment="Left" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="Orientation" Value="Vertical">
<Setter TargetName="Root" Property="LayoutTransform">
<Setter.Value>
<RotateTransform Angle="270" />
</Setter.Value>
</Setter>
<Setter TargetName="Root" Property="Width" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Height}"/>
<Setter TargetName="Root" Property="Height" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Width}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Value="False" Binding="{Binding IsChecked}">
<Setter Property="Background" Value="Red"/>
</DataTrigger>
<Trigger Value="100" Property="Value">
<Setter Property="Background" Value="Green"/>
<Setter Property="Foreground" Value="Transparent"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<DockPanel>
<ProgressBar Name="progressBarColumn" DockPanel.Dock="Top" Height="20" Minimum="0" Maximum="100"
Value="{Binding Progress, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource CustomProgressBar}" />
<StackPanel>
<Button Content="Start" Click="Button_Click"/>
<CheckBox Content="Check me" IsChecked="{Binding IsChecked}"/>
</StackPanel>
</DockPanel>
</Window>
View and viewmodel
using System;
using System.ComponentModel;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
namespace WpfApplication3
{
/// <summary>
/// Interaction logic for ProgressWindow.xaml
/// </summary>
public partial class ProgressWindow : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public ProgressWindow()
{
InitializeComponent();
DataContext = this;
}
private int _Progress;
public int Progress
{
get
{
return _Progress;
}
set
{
_Progress = value;
PropertyChanged(this, new PropertyChangedEventArgs("Progress"));
}
}
private bool _IsChecked;
public bool IsChecked
{
get
{
return _IsChecked;
}
set
{
_IsChecked = value;
PropertyChanged(this, new PropertyChangedEventArgs("IsChecked"));
}
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
Progress = 0;
await Task.Run(async () =>
{
var value = 0;
while (value < 100)
{
await Task.Delay(500);
await Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
new Action(() =>
{
Progress += 10;
}));
}
});
}
}
}

How to set CornerRadius of a wpf button border via style and databinding

I have a simple WPF Button as under:-
<Button Height="150" Width="145" Canvas.Top="8" Canvas.Left="9" x:Name="cmdButton_Template" Background="{Binding Button_BackGround}" Style="{StaticResource MyLocalButton}" Mouse.PreviewMouseUp="cmdButton_Template_PreviewMouseUp" >
<Label>
<ContentControl HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" Height="131" Canvas.Left="10" Canvas.Top="10" Width="142" >
<Canvas x:Name="ContentCanvas">
<TextBlock Canvas.Left="{Binding Text_2_Left,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Canvas.Top="{Binding Text_2_Top,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Text="{Binding Text, ElementName=txtItem_Cat_Name2,UpdateSourceTrigger=PropertyChanged}" FontSize="{Binding Font_Size_2}" FontFamily="{Binding Font_Name_2}" Foreground="{Binding Font_Color_2}" FontStyle="{Binding ElementName=chkItalic_2,Path=IsChecked,Converter={StaticResource FIC}, UpdateSourceTrigger=PropertyChanged}" TextDecorations="{Binding Font_Underline_2,Converter={StaticResource FUC}}" FontWeight="{Binding Font_Bold_2,Converter={StaticResource FVT}}" x:Name="Button_Text_2" MouseLeftButtonUp="Button_Text_2_MouseLeftButtonUp" Grid.RowSpan="3"/>
</Canvas>
</ContentControl>
</Label>
</Button>
and i have a style like this in userControl.Resources like this:
<UserControl.Resources>
<Style x:Key="MyLocalButton" TargetType="Button">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="borderZero" BorderThickness="0" BorderBrush="Black" Background="{TemplateBinding Background}" CornerRadius="{Binding AllCorners,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value="0.8" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="SomeButtonStyle" TargetType="Button">
<Setter Property="Background" Value="Black" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="{TemplateBinding Background}">
<ContentPresenter />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
This is my DataModel:
public class DM_ButtonSettings
{
public CornerRadius _AllCorners = new CornerRadius(10, 10, 10, 10);
public CornerRadius AllCorners
{
get { return _AllCorners; }
set
{
if (_AllCorners != value)
{
_AllCorners = value;
}
}
}
}
and this is my ViewModel:
public class DC_ButtonSettings:INotifyPropertyChanged
{
public CornerRadius _AllCorners = new CornerRadius(10, 10, 10, 10);
public CornerRadius AllCorners
{
get { return _AllCorners; }
set
{
if (_AllCorners != value)
{
_AllCorners = value;
RaisePropertyChangedEvent("AllCorners");
}
}
}
}
I have a ViewModel property named CornerRadius and i am trying to change the Radius of the button corners at runtime using that property by binding it to style in the local resoources of the user control.
I am passing an object of this ViewModel to the form where the Button lies,and am trying to change the Button corner radius by changing the CornerRadius programatically as per the program logic.Though the values in the ViewModel are getting changed,but the View is not getting updated.I know i am missing something very simple here,but am unable to figure out on my own.
How do i do it right?
I just removed your mode & updatesourcetrigger from the style. it's working for me.
<Style x:Key="MyLocalButton" TargetType="Button">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="borderZero" BorderThickness="2" BorderBrush="Black" Background="{TemplateBinding Background}" CornerRadius="{Binding AllCorners}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value="0.8" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Why is not Style applied for ListBoxItem?

<ListBox>
<ListBox.Resources>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="ListBoxItem.IsSelected" Value="True"/>
</Style>
</ListBox.Resources>
<ListBox>
Items are not selected.
http://www.11011.net/archives/000692.html this articale gives some cues, but ListBoxItem belongs to inheritance tree of Control class.
I know about ItemContainerStyle property. I'm just curious why style is not applied.
Update1:
It really works for ListBox, but not for derived class with the default style:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:wcl="clr-namespace:SecurityFramework.UI.WpfControlsLibrary">
<Style TargetType="{x:Type wcl:ListBoxEx}">
<Setter Property="SelectAllToggleStyle">
<Setter.Value>
<Style TargetType="ToggleButton">
<Setter Property="Content" Value="Select All"/>
<Setter Property="Focusable" Value="True"/>
<Setter Property="Margin" Value="2,0,0,0"/>
<Setter Property="IsThreeState" Value="False"/>
</Style>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type wcl:ListBoxEx}">
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="true"
Padding="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
Height="{TemplateBinding Height}"
Width="{TemplateBinding Width}">
<DockPanel VerticalAlignment="Top" HorizontalAlignment="Stretch" LastChildFill="True">
<CheckBox Name="PART_SelectAllToggle" DockPanel.Dock="Top"/>
<Separator Margin="4" Visibility="{Binding Path=Visibility, ElementName=PART_SelectAllToggle}" DockPanel.Dock="Top"/>
<ScrollViewer>
<ItemsPresenter DockPanel.Dock="Top"/>
</ScrollViewer>
</DockPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style>
<Setter Property="ListBoxItem.Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border
SnapsToDevicePixels="true"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="0"
VerticalAlignment="{TemplateBinding VerticalAlignment}"
HorizontalAlignment="Stretch"
Height="{TemplateBinding Height}"
Width="{TemplateBinding Width}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="False">
<Setter Property="Background" Value="{Binding RelativeSource={RelativeSource AncestorType=wcl:ListBoxEx, Mode=FindAncestor}, Path=ItemBackground}"/>
<Setter Property="Foreground" Value="{Binding RelativeSource={RelativeSource AncestorType=wcl:ListBoxEx, Mode=FindAncestor}, Path=ItemForeground}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{x:Static SystemColors.HighlightBrush}"/>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="{Binding RelativeSource={RelativeSource AncestorType=wcl:ListBoxEx, Mode=FindAncestor}, Path=SelectedItemBackground}"/>
<Setter Property="Foreground" Value="{Binding RelativeSource={RelativeSource AncestorType=wcl:ListBoxEx, Mode=FindAncestor}, Path=SelectedItemForeground}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Control.VerticalAlignment" Value="Center"/>
<Setter Property="Control.FocusVisualStyle">
<Setter.Value>
<Style TargetType="Control">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="0" StrokeThickness="2" Stroke="Black" SnapsToDevicePixels="true"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
<Setter Property="Padding" Value="4"/>
<Setter Property="SelectedItemBackground" Value="{x:Static SystemColors.HighlightBrush}"/>
<Setter Property="SelectedItemForeground" Value="White"/>
<Setter Property="ItemBackground" Value="Transparent"/>
<Setter Property="ItemForeground" Value="Black"/>
<Setter Property="MouseOverItemBackground" Value="LightGray"/>
<Setter Property="MouseOverItemForeground" Value="Black"/>
</Style>
</ResourceDictionary>
Update2:
parallel thread: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/f7f0558b-c041-492e-bd96-896f97a7b07e/

WPF TreeView with right alignment values

I have a problem with my wpf treeview. It's code goes like this:
<TreeView ItemsSource="{Binding Path=Items}" Grid.RowSpan="2" Grid.ColumnSpan="2">
<TreeView.Resources>
<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.Resources>
</TreeView>
Where MyTreeItem is a simple class with 2 String properties (Display and Value) and a List of MyTreeItem called Items.
I need the tree view to display all 'Values' aligned to the right, while maintaining the tree tabulation of the items 'Display', based on it's deepth.
I have tryed to set the dockPanel to a fixed width, but that didn't work.
I want to do this without any c# code, just xaml.
Thanks in advance.
If I understand your question correctly you want to Stretch the TreeViewItems and align Value to the right. To get the TreeViewItems to Stretch Horizontaly you'll need to edit the Template for TreeViewItem. The problem is explained here: http://leecampbell.blogspot.com/2009/01/horizontal-stretch-on-treeviewitems.html
Here is an edited version of the TreeViewItem which does this. Note that you'll have to add a reference to PresentationFramework.Aero for this to work
Sample
<TreeView ItemsSource="{Binding Path=Items}"
Grid.RowSpan="2"
Grid.ColumnSpan="2"
ItemContainerStyle="{StaticResource StretchTreeViewItemStyle}">
<TreeView.Resources>
<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.Resources>
</TreeView>
StretchTreeViewItemStyle
<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>
class StretchedTreeView : TreeView {
protected override void OnItemContainerStyleChanged(Style oldItemContainerStyle, Style newItemContainerStyle) {
base.OnItemContainerStyleChanged(oldItemContainerStyle, newItemContainerStyle);
newItemContainerStyle.Setters
.Add(new EventSetter(LoadedEvent, new RoutedEventHandler(TreeViewItem_Loaded)));
}
void TreeViewItem_Loaded(object sender, RoutedEventArgs e) {
TreeViewItem item = sender as TreeViewItem;
if (item == null) {
return;
}
ContentPresenter cp = FindVisualChild<ContentPresenter>(item);
cp.HorizontalAlignment = HorizontalAlignment.Stretch;
Border border = FindVisualChild<Border>(item, "Bd");
border.SetValue(Grid.ColumnSpanProperty, 2);
}
static T FindVisualChild<T>(DependencyObject obj, string name = null) where T : DependencyObject {
for (int i = 0 ; i < VisualTreeHelper.GetChildrenCount(obj) ; i++) {
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
if (child != null && child is T
&& (name == null || !(child is FrameworkElement) || name == ((FrameworkElement) child).Name)) {
return (T) child;
}
else {
T childOfChild = FindVisualChild<T>(child, name);
if (childOfChild != null) {
return childOfChild;
}
}
}
return null;
}
}

Resources