Reputation: 147
I want to change the icon on my button. Here is the xaml of my button:
<Button Name="InitPurgeBtn" Click="InitPurgeClick">
<Rectangle Width="35" Height="45" Margin="0,0,0,0">
<Rectangle.Fill>
<VisualBrush Stretch="Fill" Visual="{StaticResource InitIcon}" />
</Rectangle.Fill>
</Rectangle>
</Button>
The probleme is I don't know how to acces the Visual property of the Rectangle of my button in my controller to change "InitIcon" by "PurgeIcon" All my icon are implement in xaml:
<Viewbox x:Key="ExtinctionIcon" Stretch="Uniform" x:Shared="False">
<Canvas Width="76" Height="76" Clip="F1 M 0,0L 76,0L 76,76L 0,76L 0,0">
<Path Width="40" Height="40" Stretch="Fill" Fill="{Binding Foreground,
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}"
Data="M15,24H17V22H15M16.56,{...}24H13V22H11M7,24H9V22H7V24Z"/>
</Canvas>
</Viewbox>
Edit :
I change my button and he is like this now :
<Button Name="InitBtn" Style="{StaticResource RoundButton}" Width="70" Height="70"
Click="InitPurgeClick" Content="{StaticResource InitIcon}">
</Button>
I want to change the icon in my code so I try to set Content property like this :
InitBtn.Content = "{StaticResource ExtinctionIcon}";
But this way just replace my icon with the string "StaticResource.."
Upvotes: 1
Views: 184
Reputation: 16991
Updated to reflect new information
You updated your question with some new information that changes things a lot.
Since you are trying to update Button.Content
in code, you won't be able to use the MarkupExtension
. MarkupExtensions (the stuff inside { } in the XAML) are only evaluated when the view is initially created. After that, they behave just like regular strings, so trying to set one in code won't work.
To set the value in code, you will need to manually do what the MarkupExtension
is doing; find the resource by name, and set the value directly. You can do this with the following code (assuming a reference to InitPurgeBtn
).
InitPurgeBtn.Content = InitPurgeBtn.FindResource("ExtinctionIcon");
Previous Answer
You should be able to add your icon to the Content
of the Button
directly, as it seems to be defined as a resource somewhere (because of the x:Key
attribute). Your code doesn't show where exactly that is though, so I can't grantee this will work without some modification.
<Button Name="InitPurgeBtn"
Width="100"
Height="40"
Content="{StaticResource ExtinctionIcon}" />
In order for that to work the ExtinctionIcon
resource will have to be defined someplace accessible to the button, meaning either in an ancestor of the button, or in App.xaml
.
The fact that the resource is defined with x:Shared="false"
seems to indicate that it was designed to be used in exactly this way, as that is required for visual elements that can possibly be hosted in multiple places simultaneously.
Alternatively, you could just copy and embed the icon directly in to the button.
<Button Name="InitPurgeBtn"
Click="InitPurgeClick">
<Viewbox Stretch="Uniform">
<Canvas Width="76"
Height="76"
Clip="F1 M 0,0L 76,0L 76,76L 0,76L 0,0">
<Path Width="40"
Height="40"
Stretch="Fill"
Fill="{Binding Foreground,
RelativeSource={RelativeSource
Mode=FindAncestor,
AncestorType=Button}}"
Data="M15,24H17V22H15M16.56,{...}24H13V22H11M7,24H9V22H7V24Z"/>
</Canvas>
</Viewbox>
</Button>
Upvotes: 1
Reputation: 4546
If you just want a single (xaml) icon, you can bind the content property of your button to your icon resource.
The control below gives an enhanced display - a xaml icon plus a text caption, including two colours for the icon and support for disabled state.
MyXamlIconHost.cs
public enum CaptionPosition { None, ToLeftOfIcon, AboveIcon, ToRightOfIcon, BelowIcon }
public enum IconSize { Small, Medium, Large, XLarge, XxLarge }
public class myXamlIconHost : Control
{
private static readonly Brush DefaultForeground = new SolidColorBrush(Color.FromRgb(32,32,32));
private static readonly Brush DefaultHighlight = Brushes.DarkOrange;
private static readonly Brush DefaultDisabledForeground = new SolidColorBrush(Color.FromRgb(192, 192, 192));
private static readonly Brush DefaultDisabledHighlight = new SolidColorBrush(Color.FromRgb(128, 128, 128));
static myXamlIconHost()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(myXamlIconHost), new FrameworkPropertyMetadata(typeof(myXamlIconHost)));
}
public FrameworkElement XamlIcon
{
get { return (FrameworkElement)GetValue(XamlIconProperty); }
set { SetValue(XamlIconProperty, value); }
}
public static readonly DependencyProperty XamlIconProperty =
DependencyProperty.Register("XamlIcon", typeof(FrameworkElement), typeof(myXamlIconHost), new PropertyMetadata(null));
public IconSize IconSize
{
get { return (IconSize)GetValue(IconSizeProperty); }
set { SetValue(IconSizeProperty, value); }
}
public static readonly DependencyProperty IconSizeProperty =
DependencyProperty.Register("IconSize", typeof(IconSize), typeof(myXamlIconHost), new PropertyMetadata(IconSize.Medium));
public string Caption
{
get { return (string)GetValue(CaptionProperty); }
set { SetValue(CaptionProperty, value); }
}
public static readonly DependencyProperty CaptionProperty =
DependencyProperty.Register("Caption", typeof(string), typeof(myXamlIconHost), new PropertyMetadata(null));
public CaptionPosition CaptionPosition
{
get { return (CaptionPosition)GetValue(CaptionPositionProperty); }
set { SetValue(CaptionPositionProperty, value); }
}
public static readonly DependencyProperty CaptionPositionProperty =
DependencyProperty.Register("CaptionPosition", typeof(CaptionPosition), typeof(myXamlIconHost), new PropertyMetadata(CaptionPosition.ToRightOfIcon));
public Brush StandardForeground
{
get { return (Brush)GetValue(StandardForegroundProperty); }
set { SetValue(StandardForegroundProperty, value); }
}
public static readonly DependencyProperty StandardForegroundProperty =
DependencyProperty.Register("StandardForeground", typeof(Brush), typeof(myXamlIconHost), new PropertyMetadata(DefaultForeground));
public Brush StandardHighlight
{
get { return (Brush)GetValue(StandardHighlightProperty); }
set { SetValue(StandardHighlightProperty, value); }
}
public static readonly DependencyProperty StandardHighlightProperty =
DependencyProperty.Register("StandardHighlight", typeof(Brush), typeof(myXamlIconHost), new PropertyMetadata(DefaultHighlight));
public Brush DisabledForeground
{
get { return (Brush)GetValue(DisabledForegroundProperty); }
set { SetValue(DisabledForegroundProperty, value); }
}
public static readonly DependencyProperty DisabledForegroundProperty =
DependencyProperty.Register("DisabledForeground", typeof(Brush), typeof(myXamlIconHost), new PropertyMetadata(DefaultDisabledForeground));
public Brush DisabledHighlight
{
get { return (Brush)GetValue(DisabledHighlightProperty); }
set { SetValue(DisabledHighlightProperty, value); }
}
public static readonly DependencyProperty DisabledHighlightProperty =
DependencyProperty.Register("DisabledHighlight", typeof(Brush), typeof(myXamlIconHost), new PropertyMetadata(DefaultDisabledHighlight));
}
// ==============================================================================================================================================
public class myXamlIconSizeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
const int defaultSize = 24;
if (!(value is IconSize))
return defaultSize;
var iconSizeValue = (IconSize)value;
switch (iconSizeValue)
{
case IconSize.Small:
return defaultSize * 2 / 3;
case IconSize.Large:
return defaultSize * 3 / 2;
case IconSize.XLarge:
return defaultSize * 2;
case IconSize.XxLarge:
return defaultSize * 5 / 2;
default:
return defaultSize;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
}
MyXamlIconHost.xaml
<Style TargetType="{x:Type ctrl:myXamlIconHost}">
<Setter Property="Focusable" Value="False" />
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="Padding" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ctrl:myXamlIconHost}">
<Grid Margin="{TemplateBinding Padding}">
<Grid.Resources>
<ctrl:myXamlIconSizeConverter x:Key="IconSizeConverter" />
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock x:Name="PART_CaptionTextBlock"
Grid.Row="1"
Grid.Column="0"
Margin="8,0,8,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{TemplateBinding StandardForeground}"
Text="{TemplateBinding Caption}" />
<!-- Set DataContext to "self" so that the Xaml Icon item can bind to the Foreground and BorderBrush properties -->
<ContentControl x:Name="PART_IconPresenter"
Grid.Row="1"
Grid.Column="1"
Width="{TemplateBinding IconSize,
Converter={StaticResource IconSizeConverter}}"
Height="{TemplateBinding IconSize,
Converter={StaticResource IconSizeConverter}}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
BorderBrush="{TemplateBinding StandardHighlight}"
Content="{TemplateBinding XamlIcon}"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Focusable="False"
Foreground="{TemplateBinding StandardForeground}" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="PART_CaptionTextBlock" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DisabledForeground}" />
<Setter TargetName="PART_IconPresenter" Property="BorderBrush" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DisabledHighlight}" />
<Setter TargetName="PART_IconPresenter" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DisabledForeground}" />
</Trigger>
<Trigger Property="CaptionPosition" Value="None">
<Setter TargetName="PART_CaptionTextBlock" Property="Visibility" Value="Collapsed" />
</Trigger>
<Trigger Property="CaptionPosition" Value="ToLeftOfIcon">
<Setter TargetName="PART_CaptionTextBlock" Property="Grid.Column" Value="0" />
<Setter TargetName="PART_CaptionTextBlock" Property="Grid.Row" Value="1" />
<Setter TargetName="PART_CaptionTextBlock" Property="Margin" Value="8,0,8,0" />
</Trigger>
<Trigger Property="CaptionPosition" Value="ToRightOfIcon">
<Setter TargetName="PART_CaptionTextBlock" Property="Grid.Column" Value="2" />
<Setter TargetName="PART_CaptionTextBlock" Property="Grid.Row" Value="1" />
<Setter TargetName="PART_CaptionTextBlock" Property="Margin" Value="8,0,8,0" />
</Trigger>
<Trigger Property="CaptionPosition" Value="AboveIcon">
<Setter TargetName="PART_CaptionTextBlock" Property="Grid.Column" Value="1" />
<Setter TargetName="PART_CaptionTextBlock" Property="Grid.Row" Value="0" />
<Setter TargetName="PART_CaptionTextBlock" Property="Margin" Value="8,0,8,4" />
</Trigger>
<Trigger Property="CaptionPosition" Value="BelowIcon">
<Setter TargetName="PART_CaptionTextBlock" Property="Grid.Column" Value="1" />
<Setter TargetName="PART_CaptionTextBlock" Property="Grid.Row" Value="2" />
<Setter TargetName="PART_CaptionTextBlock" Property="Margin" Value="8,4,8,0" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
Example Usage
<Window ... >
<Window.Resources>
<Grid x:Key="TestIcon" x:Shared="False" Background="Transparent">
<Path Stretch="Fill" Data=" M 0,0 M 100,100 M 0,0 L 0,100 L 100,100 L 100,60 L 90,60 L 90,90 L 10,90 L 10,10 L 90,10 L 90,40 L 100,40 L 100,0 z" Fill="{ Binding Foreground, FallbackValue=Cyan}"/>
<Path Stretch="Fill" Data=" M 0,0 M 100,100 M 70,45 L 100,45 L 100,55 L 70,55 z" Fill="{ Binding BorderBrush, FallbackValue=Magenta}"/>
</Grid>
</Window.Resources>
<Button HorizontalAlignment="Center" VerticalAlignment="Center">
<Border Background="LightBlue">
<ctrls:myXamlIconHost Caption="The Caption" XamlIcon="{StaticResource TestIcon}" IconSize="XxLarge" Padding="20" />
</Border>
</Button>
</Window>
Upvotes: 0
Reputation: 930
You may use Content
property.
<Button Name="InitPurgeBtn" Width="100" Height="40">
<Button.Content>
<Image Source=".\Icon.PNG"/>
</Button.Content>
</Button>
Upvotes: 1