I'm using SharpVectors to embed svg file in my XAML.
Here is my Button
ControlTemplate
:
<ControlTemplate x:Key="ButtonTemplate" TargetType="Button">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
SnapsToDevicePixels="True">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<svgc:SvgViewbox x:Name="svgIcon" Grid.Column="0" Margin="{TemplateBinding Padding}" Height="20" Width="20" Stretch="Uniform" />
<customUserControl:ExtendedBinding Grid.Column="0"
Source="{Binding ElementName=svgIcon,Path=Source,Mode=TwoWay}"
Target="{Binding Path=Tag, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" />
<ContentPresenter x:Name="contentPresenter"
Grid.Column="1"
Focusable="False"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Grid>
</Border>
</ControlTemplate>
And here is an example of creating a button:
<Button Content="Text" Tag="../../../../Assets/Icons/cross.svg" Click="OnClick"/>
What I obtain is a SVG icon with a text inside my button.
Now I'd like to change the background color of my SVG on MouseOver
(exactly the same behaviour asked here, the difference is that I do not have a "Fill" tag in my svgc:SvgViewbox
.
Is there a way to solve my problem?
Update: My SVG file is a standard SVG, like this:
<g>
<g>
<path d="M311.517,14.053c-99.265,0-180.024,80.66-180.024,179.805c0,41.538,14.182,79.827,37.955,110.303L0,451.176l22.889,26.313 l170.577-147.994c31.628,27.496,72.926,44.168,118.051,44.168c99.266,0,180.025-80.661,180.025-179.805 C491.542,94.713,410.784,14.053,311.517,14.053z M311.517,353.663c-88.237,0-160.024-71.688-160.024-159.805 S223.279,34.053,311.517,34.053s160.025,71.688,160.025,159.805S399.755,353.663,311.517,353.663z" fill="#FFFFFF"/>
<polygon points="322.447,122.812 300.587,122.812 300.587,182.928 240.471,182.928 240.471,204.788 300.587,204.788 300.587,264.904 322.447,264.904 322.447,204.788 382.563,204.788 382.563,182.928 322.447,182.928 " fill="#000000"/>
</g>
</g>
There must be multiple GeomtryDrawing
's in your svg XAML
like below :
<DrawingGroup>
<GeometryDrawing Brush="#FF71BF22">
<GeometryDrawing.Geometry>
<PathGeometry FillRule="Nonzero" Figures="M546.394,327.725L536.856,272.111 507.584,214.272C507.584,214.272,493.855,193.075,471.075,197.47L498.963,334.022 546.394,327.725z" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
Search for all such Brush
in your code and change their values, thus creating two copies of your SVG XAML
, then using Trigger
swap these on MouseOver
.
EDIT #1 (based on OP's 1st comment)
You can use an AttachedProperty
to handle MouseEnter
and MouseLeave
events for your Path
. This AP allows you to set the transparency level.
Your Path
must be under Grid
.
public static byte GetSvgProp(DependencyObject obj)
{
return (byte)obj.GetValue(SvgPropProperty);
}
public static void SetSvgProp(DependencyObject obj, byte value)
{
obj.SetValue(SvgPropProperty, value);
}
// Using a DependencyProperty as the backing store for SvgProp. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SvgPropProperty =
DependencyProperty.RegisterAttached("SvgProp", typeof(byte), typeof(Window2), new PropertyMetadata((byte)0xFF, new PropertyChangedCallback(SvgPropChanged)));
private static void SvgPropChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((Grid)d).Loaded += (s, args) => {
var paths = ((Grid)s).Children.OfType<Path>();
foreach (Path p in paths)
{
p.MouseEnter += (s1, args1) => {
Path p1 = (Path)s1;
p1.Tag = p1.Fill; // save old value
var c = ((SolidColorBrush)p1.Fill).Color;
Color newColor = new Color() { A=(byte)e.NewValue, R = c.R, G = c.G, B = c.B };
p1.Fill = new SolidColorBrush() { Color = newColor };
};
p.MouseLeave += (s2, args2) => {
Path p2 = (Path)s2;
//p2.Fill.Opacity = 1.0;
p2.Fill = (Brush)p2.Tag; // revert back to old value
};
}
};
}
Assuming your SVG code is in a Grid
:
<Grid local:Window2.SvgProp="0x23">
<Path Fill="Red" Data="M311.517,14.053c-99.265,0-180.024,80.66-180.024,179.805c0,41.538,14.182,79.827,37.955,110.303L0,451.176l22.889,26.313 l170.577-147.994c31.628,27.496,72.926,44.168,118.051,44.168c99.266,0,180.025-80.661,180.025-179.805 C491.542,94.713,410.784,14.053,311.517,14.053z M311.517,353.663c-88.237,0-160.024-71.688-160.024-159.805 S223.279,34.053,311.517,34.053s160.025,71.688,160.025,159.805S399.755,353.663,311.517,353.663z"/>
<Polygon Points="322.447,122.812 300.587,122.812 300.587,182.928 240.471,182.928 240.471,204.788 300.587,204.788 300.587,264.904 322.447,264.904 322.447,204.788 382.563,204.788 382.563,182.928 322.447,182.928 " Fill="#000000"/>
</Grid>