WPF 如何自定义图标-续篇
引言
前面WPF 如何自定义图标-前言我们讲过,使用StreamGeometry在XAML文件中进行包括,将图标的数据以字符串的形式传递给StreamGeometry,然后再将StreamGeometry作为静态资源在我们的项目中使用。虽然上面可以满足我们的一般要求,但是当我们后台使用相同的资源时,比较麻烦:通过资源名找到对应的资源。当资源较多时,理论上会增加检索负担。因此我想通过某种方式,同时方便XAML和CS使用图标资源,同时也不额外增加性能开销,最好能统一使用方式。
应用
通过学习别人的项目和总结。发下可以通过属性来解决以上问题。具体就是将不同的图标资源定义成一个string类型的属性,在XAML中将该属性的类以资源的形式引入(得到单个实例),在CS中直接New一个实例来使用。为了节省开销,图标资源类定义时,使用只读属性。
1.图标资源的定义 MaterialIconSource.cs
public class MaterialIconSource
{
public string Add { get; } = "M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M13,7H11V11H7V13H11V17H13V13H17V11H13V7Z";
public string Arrow { get; } = "M5,17.59L15.59,7H9V5H19V15H17V8.41L6.41,19L5,17.59Z";
public string Back { get; } = "M20,11V13H8L13.5,18.5L12.08,19.92L4.16,12L12.08,4.08L13.5,5.5L8,11H20Z";
public string Border { get; } = "M3,21V3H21V21H3M5,5V19H19V5H5Z";
}
这里只是列举了部分,在我们的项目中,这一块的资源应该和实际项目的需求相匹配。
2.定义本地服务ServiceLocator.cs
namespace Deamon.View.PERSONALIZATION.IconUsage
{
public class ServiceLocator
{
public MaterialIconSource IconSource { get; } = new MaterialIconSource();
}
}
这里也可以将IconSource定义成静态属性。
3.在xaml文件中使用
3.1在App.XAML.cs中定义静态资源
<Application x:Class="Deamon.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Deamon"
xmlns:iconBase="clr-namespace:Deamon.View.PERSONALIZATION.IconUsage"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<iconBase:ServiceLocator x:Key="ServiceLocator"/>
</ResourceDictionary>
</Application.Resources>
</Application>
3.2在其他View中使用图标资源
<UserControl x:Class="Deamon.View.PERSONALIZATION.IconUsage.IconUsageView"
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:Deamon.View.PERSONALIZATION.IconUsage"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<StackPanel>
<Path Data="{Binding IconSource.Arrow,Source={StaticResource ServiceLocator}}"
Fill="Red"/>
<Path Data="{Binding IconSource.Add,Source={StaticResource ServiceLocator}}"
Fill="Red"/>
</StackPanel>
</Grid>
</UserControl>
3.3效果
右边红色图标
4.在CS文件中使用
public partial class PersonalizationHomeViewModel : ViewModelBase
{
// 定义本地服务实例(里面包含必要的资源)
private readonly IconUsage.ServiceLocator mServiceLocator = new IconUsage.ServiceLocator();
public PersonalizationHomeViewModel()
{
SelectedCommand = new RelayCommand<ItemModel>(p =>
{
switch (p.ItemViewText)
{
case "Background":
ViewContent = new BackgroundView();
break;
case "DataGridUsage":
ViewContent = new DataGridUsage.DataGridView();
break;
case "IconUsage":
ViewContent = new IconUsage.IconUsageView();
break;
default:
break;
}
});
ViewItems = new List<ItemModel>()
{
new ItemModel() { ItemViewText = "Background", ItemViewGlyph= mServiceLocator.IconSource.Back},
new ItemModel() { ItemViewText = "DataGridUsage", ItemViewGlyph= mServiceLocator.IconSource.Trim },
new ItemModel() { ItemViewText = "IconUsage", ItemViewGlyph= mServiceLocator.IconSource.Ellipse },
new ItemModel() { ItemViewText = "...", ItemViewGlyph= mServiceLocator.IconSource.More },
};
SelectedViewItem = ViewItems.FirstOrDefault();
}
}
上图中对ViewItems的ItemViewGlyph属性赋值的就是图形的字符串。
左边黑色图标
总结
通过以上的操作,我们可以简单的实现自身项目自定义图标资源的定义和使用了。这样就可以在我们的项目中运用了。并在实际开发中总结,让项目结构变得更加便利好用。