第一步,在App.xaml中定义一个Path路径资源
<ResourceDictionary>
<!--Setting Image-->
<PathFigureCollection x:Key="SettingPathData">
M704.334 320.166c-166.812-169.952-465.88-48.558-464.332 192.338C239.94 662.402 362.098 784.56 512 784.5c240.882 1.53 362.304-297.542 192.334-464.334zM403.722 564.208l-52.752 52.752c-40.834-59.18-40.832-149.744 0-208.922l52.752 52.752c-15.494 30.922-15.494 72.498 0 103.418zM512 704.5c-38.494 0-74.378-11.388-104.462-30.97l52.752-52.752c30.922 15.494 72.496 15.494 103.416 0l52.752 52.752c-30.08 19.582-65.964 30.97-104.458 30.97z m-40-192c1.386-52.746 78.622-52.734 80 0.002-1.386 52.744-78.622 52.732-80-0.002z m91.708-108.278c-30.922-15.494-72.496-15.494-103.416 0l-52.752-52.752c59.18-40.834 149.744-40.832 208.922 0z m109.322 212.74l-52.752-52.752c15.494-30.922 15.494-72.496 0-103.416l52.752-52.752c40.834 59.176 40.832 149.742 0 208.92zM942.182 552a427.98 427.98 0 0 1-17.38 87.756l38.618 16.132c48 21.43 18.526 92.942-30.838 73.818l-73.722-30.798c-20.346-8.5-29.976-31.858-21.534-52.226C934.62 419.844 758.972 156.86 511.996 160.002 264.78 156.74 89.018 420.788 186.958 647.098c92.744 228.914 400.552 291.228 573.942 113.8 15.71-15.716 41.11-15.506 56.57 0.004l56.568 56.57c36.262 38.032-18.176 93.032-56.572 56.568l-29.566-29.566a430.85 430.85 0 0 1-74.106 49.736l15.954 38.47c11.28 25.588-9.176 55.858-36.934 55.332-35.862-0.06-40.802-37.542-52.918-63.158A430.828 430.828 0 0 1 552 942.186V984c0 22.092-17.908 40-40 40s-40-17.908-40-40v-41.816a430.8 430.8 0 0 1-87.896-17.332c-12.154 25.694-17.04 63.072-52.918 63.158-27.756 0.52-48.216-29.742-36.932-55.332l15.952-38.47a430.772 430.772 0 0 1-74.106-49.736l-29.566 29.568c-15.622 15.62-40.946 15.622-56.568 0-15.622-15.62-15.624-40.948-0.002-56.568l29.568-29.568a430.866 430.866 0 0 1-49.736-74.108c-10.89 3.556-42.344 20.156-53.776 19.014-43.308-0.474-55.656-59.508-15.338-76.96l38.47-15.952a430.828 430.828 0 0 1-17.332-87.896H40c-22.092 0-40-17.908-40-40s17.908-40 40-40h41.816a430.8 430.8 0 0 1 17.332-87.896l-38.47-15.952c-48.206-22.272-19.156-92.276 30.644-73.898l38.47 15.952a430.866 430.866 0 0 1 49.736-74.108L149.96 206.53c-15.622-15.622-15.62-40.948 0.002-56.568 15.62-15.62 40.946-15.62 56.568 0l29.566 29.568a430.85 430.85 0 0 1 74.106-49.736l-15.954-38.47c-8.462-20.406 1.22-43.808 21.626-52.272 20.406-8.462 43.808 1.22 52.272 21.626l15.954 38.47a430.828 430.828 0 0 1 87.896-17.332V40c0-22.092 17.908-40 40-40s40 17.908 40 40v41.816a430.8 430.8 0 0 1 87.896 17.332l15.954-38.47c8.464-20.408 31.866-30.086 52.272-21.626 20.406 8.462 30.09 31.866 21.626 52.272l-15.954 38.47a430.772 430.772 0 0 1 74.106 49.736l29.566-29.568c15.622-15.622 40.948-15.622 56.568 0 15.622 15.62 15.624 40.948 0.002 56.568l-29.568 29.568a430.866 430.866 0 0 1 49.736 74.108l38.47-15.952c20.404-8.46 43.808 1.22 52.272 21.626s-1.22 43.81-21.626 52.272l-38.47 15.952A430.8 430.8 0 0 1 942.178 472H984c22.092 0 40 17.908 40 40s-17.908 40-40 40z
</PathFigureCollection>
</ResourceDictionary>
第二步,新建一个UserControl类
<UserControl x:Class="ReadXLS.Custom.MenuButton"
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"
xmlns:local="clr-namespace:ReadXLS.Custom"
mc:Ignorable="d" >
<Grid x:Name="_contaier" Height="50">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Image x:Name="_image" Grid.Column="0" Width="25" Height="25" Margin="15 0 15 0"/>
<TextBlock x:Name="_textBlock" Grid.Column="1" Text="菜单" Foreground="#666D73" FontSize="20" VerticalAlignment="Center" FontWeight="Light" />
</Grid>
</UserControl>
第三步,写一些依赖属性
/// <summary>
/// MenuButton.xaml 的交互逻辑
/// </summary>
public partial class MenuButton : UserControl
{
private SolidColorBrush selectBackground = new SolidColorBrush(Color.FromRgb(31, 37, 35));
private SolidColorBrush enterBackground = new SolidColorBrush(Color.FromRgb(48, 56, 59));
private PathGeometry pathGeometry = new PathGeometry();
private GeometryDrawing geometryDrawing = new GeometryDrawing();
public MenuButton()
{
InitializeComponent();
}
/// <summary>
/// Path路径集合
/// </summary>
public PathFigureCollection PathFigures
{
get { return (PathFigureCollection)GetValue(PathFiguresProperty); }
set { SetValue(PathFiguresProperty, value); }
}
public static readonly DependencyProperty PathFiguresProperty =
DependencyProperty.Register("PathFigures", typeof(PathFigureCollection), typeof(MenuButton), new PropertyMetadata(null,new PropertyChangedCallback(PathFiguresPropertyChangedCallback)));
private static void PathFiguresPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (!(d is MenuButton source)) return;
if (!(e.NewValue is PathFigureCollection figure)) return;
source.pathGeometry.Figures = figure;
source.geometryDrawing.Geometry = source.pathGeometry;
source.geometryDrawing.Brush = source.Foreground;
source._image.Source = new DrawingImage(source.geometryDrawing);
}
/// <summary>
/// 按钮文本
/// </summary>
public new string Content
{
get { return (string)GetValue(ContentProperty); }
set { SetValue(ContentProperty, value); }
}
public static new readonly DependencyProperty ContentProperty =
DependencyProperty.Register("Content", typeof(string), typeof(MenuButton), new PropertyMetadata("",new PropertyChangedCallback(ContentPropertyChangedCallback)));
private static void ContentPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (!(d is MenuButton source)) return;
if (!(e.NewValue is string content)) return;
source._textBlock.Text = content;
}
/// <summary>
/// 前景色
/// </summary>
public new Brush Foreground
{
get { return (Brush)GetValue(ForegroundProperty); }
set { SetValue(ForegroundProperty, value); }
}
public static new readonly DependencyProperty ForegroundProperty =
DependencyProperty.Register("Foreground", typeof(Brush), typeof(MenuButton), new PropertyMetadata(new SolidColorBrush(Color.FromRgb(102, 109, 115)),new PropertyChangedCallback(ForegroundPropertyChangedCallback) ));
private static void ForegroundPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (!(d is MenuButton source)) return;
if (!(e.NewValue is Brush brush)) return;
source.geometryDrawing.Brush = brush;
source._textBlock.Foreground = brush;
}
/// <summary>
/// 背景色
/// </summary>
public new Brush Background
{
get { return (Brush)GetValue(BackgroundProperty); }
set { SetValue(BackgroundProperty, value); }
}
public static new readonly DependencyProperty BackgroundProperty =
DependencyProperty.Register("Background", typeof(Brush), typeof(MenuButton), new PropertyMetadata(null,new PropertyChangedCallback(BackgroundPropertyChangedCallback)));
private static void BackgroundPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (!(d is MenuButton source)) return;
if (!(e.NewValue is Brush brush)) return;
source._contaier.Background = brush;
}
}
第四步,调用这个自定义控件
<custom:MenuButton PathFigures="{StaticResource SettingPathData}" Content="工作站"/>
这里直接将SettingPathData路径资源传入自定义依赖属性PathFigures当中,由于我们重写了Foreground和Background,所以还可以很方便的改变他们的颜色,效果如下
这样我们就利用了SVG的路径实现了图标功能,而且图标的颜色可以自定义,非常方便。
重点是PathGeometry 和GeometryDrawing 两个类,一个加载路径,一个绘制成图源。