Reputation: 65
I've defined this style :
<Style x:Key="ButtonIcon" TargetType="{x:Type local:ButtonIcon}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="Padding" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ButtonIcon}">
<Path x:Name="IconPath" Stretch="Uniform" Height="10" Margin="5"
Fill="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IconFill}"
Stroke="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IconStroke}"
Data="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IconData}" />
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Transparent" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="Transparent" />
<Setter Property="IconFill" Value="Transparent"/>
</Trigger>
</Style.Triggers>
</Style>
which is basically a button with a path as content and where I've defined new properties IconFill
, IconStroke
and IconData
.
Here is the ButtonIcon
class:
Public Class ButtonIcon
Inherits Button
Implements INotifyPropertyChanged
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Public Sub New()
DefaultStyleKeyProperty.OverrideMetadata(GetType(ButtonIcon), New FrameworkPropertyMetadata(GetType(ButtonIcon)))
End Sub
Public Shared ReadOnly Property IconFillProperty As DependencyProperty = DependencyProperty.Register("IconFill", GetType(Brush), GetType(ButtonIcon), New UIPropertyMetadata(Brushes.Transparent))
Public Property IconFill As Brush
Get
Return GetValue(IconFillProperty)
End Get
Set(value As Brush)
SetValue(IconFillProperty, value)
NotifyPropertyChanged()
End Set
End Property
Public Shared ReadOnly Property IconStrokeProperty As DependencyProperty = DependencyProperty.Register("IconStroke", GetType(Brush), GetType(ButtonIcon), New UIPropertyMetadata(Brushes.Transparent))
Public Property IconStroke As Brush
Get
Return GetValue(IconStrokeProperty)
End Get
Set(value As Brush)
SetValue(IconStrokeProperty, value)
NotifyPropertyChanged()
End Set
End Property
Public Shared ReadOnly Property IconDataProperty As DependencyProperty = DependencyProperty.Register("IconData", GetType(Geometry), GetType(ButtonIcon), New UIPropertyMetadata())
Public Property IconData As Geometry
Get
Return GetValue(IconDataProperty)
End Get
Set(value As Geometry)
SetValue(IconDataProperty, value)
NotifyPropertyChanged()
End Set
End Property
Protected Sub NotifyPropertyChanged(<CallerMemberName> Optional propertyName As String = "")
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
End Class
and usage:
<local:ButtonIcon x:Name="BtColor1" Style="{DynamicResource ButtonIcon}"
IconFill="{Binding MediaColor1.FillBrush}"
IconStroke="{Binding MediaColor1.StrokeBrush}"
IconData="{DynamicResource Icons.Circle}" />
Everything is as expected except that when the button is pressed, the Path Fill color doesn't become transparent.
As the Path Fill property is directly bind to the button IconFill
I don't understand where is the error.
I've also tried to implement INotifyPropertyChanged
on ButtonIcon
class but without success.
Lastly I know that IsPressed
trigger is working because if I change background value to some visible color I correctly see that color when I press the button.
Upvotes: 0
Views: 525
Reputation: 189
Try moving your triggers into the ControlTemplate
and reference the component's name in the setters.
My ButtonIcon.xaml
file:
<Style x:Key="ButtonIcon" TargetType="{x:Type local:ButtonIcon}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="Padding" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ButtonIcon}" >
<Border Name="Border"
Background="{TemplateBinding Background}"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
CornerRadius="{TemplateBinding CornerRadius}">
<Path Name="IconPath" Stretch="Uniform" Height="10" Margin="5"
Fill="{TemplateBinding IconFill}"
Stroke="{TemplateBinding IconStroke}"
Data="{TemplateBinding IconData}" >
</Path>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Border" Property="Background" Value="Transparent" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="Border" Property="Background" Value="Transparent" />
<Setter TargetName="IconPath" Property="Fill" Value="Red" />
<Setter TargetName="IconPath" Property="Stroke" Value="Red" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type local:ButtonIcon}" BasedOn="{StaticResource ButtonIcon}" />
Usage:
<local:ButtonIcon Width="100" Height="50"
BorderThickness="1"
Background="#2F2F2F"
CornerRadius="5"
BorderBrush="DimGray"
IconFill="#48A999"
IconStroke="#48A999"
IconData="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z"
Cursor="Hand">
</local:ButtonIcon>
The component:
The component when moused over and pressed:
Path
in a Border
and changed the trigger colors just to see it better on the UI while trying it out.Here's the ButtonIcon.cs
class file I used for the example:
public class ButtonIcon : Button
{
static ButtonIcon()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ButtonIcon), new FrameworkPropertyMetadata(typeof(ButtonIcon)));
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
}
#region Dependency Properties
/// <summary>
/// The button's corner radius.
/// </summary>
public static readonly DependencyProperty CornerRadiusProperty =
DependencyProperty.Register(nameof(CornerRadius),
typeof(CornerRadius), typeof(ButtonIcon), new PropertyMetadata(new CornerRadius(0)));
public CornerRadius CornerRadius
{
get => (CornerRadius)GetValue(CornerRadiusProperty);
set => SetValue(CornerRadiusProperty, value);
}
/// <summary>
/// The icon's fill color.
/// </summary>
public static readonly DependencyProperty IconFillProperty =
DependencyProperty.Register(nameof(IconFill),
typeof(Brush), typeof(ButtonIcon), new PropertyMetadata(Brushes.Black));
public Brush IconFill
{
get => (Brush)GetValue(IconFillProperty);
set => SetValue(IconFillProperty, value);
}
/// <summary>
/// The icon's stroke color.
/// </summary>
public static readonly DependencyProperty IconStrokeProperty =
DependencyProperty.Register(nameof(IconStroke),
typeof(Brush), typeof(ButtonIcon), new PropertyMetadata(Brushes.Black));
public Brush IconStroke
{
get => (Brush)GetValue(IconStrokeProperty);
set => SetValue(IconStrokeProperty, value);
}
/// <summary>
/// The icon's path data.
/// </summary>
public static readonly DependencyProperty IconDataProperty =
DependencyProperty.Register(nameof(IconData),
typeof(Geometry), typeof(ButtonIcon), new PropertyMetadata(null));
public Geometry IconData
{
get => (Geometry)GetValue(IconDataProperty);
set => SetValue(IconDataProperty, value);
}
#endregion
}
Upvotes: 1