【发布时间】:2017-02-20 22:20:33
【问题描述】:
如何在 .XAML 中或以编程方式实现这一点?
<Image>
<!--<iconPacks:PackIconMaterial Kind="{Binding Status}"/>-->
</Image>
【问题讨论】:
如何在 .XAML 中或以编程方式实现这一点?
<Image>
<!--<iconPacks:PackIconMaterial Kind="{Binding Status}"/>-->
</Image>
【问题讨论】:
我有同样的问题。
我使用的包只允许System.Windows.Controls.Image
我从 C# 端解决了。
让我们创建一个 Mahapps 图标
PackIconFontAwesome icon = new PackIconFontAwesome();
icon.Kind = PackIconFontAwesomeKind.AddressBook;
并转换为Geometry
Geometry geo = Geometry.Parse(icon.Data);
GeometryDrawing gd = new GeometryDrawing();
gd.Geometry = geo;
gd.Brush = icon.BorderBrush;
gd.Pen = new Pen(Brushes.White, 100);
icon.Data 给出图标 Path Markup Syntax 的 XAML 路径
现在我们可以转换为Image How to: Use a Drawing as an Image Source
DrawingImage geoImage = new DrawingImage(gd);
geoImage.Freeze();
Image img = new Image();
img.Source = geoImage;
现在你可以绑定任何你想要的地方。
【讨论】:
使用转换器是最简单的方法(扩展了 tetralobita 的答案),但我没有看到需要创建一堆模板类,所以这里是一个只使用一个转换器的工作版本:
namespace MyProject.Converters
{
/// <summary>
/// Converts a <see cref="PackIcon{TKind}" /> to an DrawingImage.
/// Use the ConverterParameter to pass a Brush.
/// </summary>
public class PackIconToImageConverter : IValueConverter
{
/// <summary>
/// Gets or sets the thickness to draw the icon with.
/// </summary>
public double Thickness { get; set; } = 0.25;
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
GeometryDrawing geoDrawing = new GeometryDrawing();
geoDrawing.Brush = parameter as Brush ?? Brushes.Black;
geoDrawing.Pen = new Pen(geoDrawing.Brush, Thickness);
if (value is PackIconFontAwesome)
geoDrawing.Geometry = Geometry.Parse((value as PackIcon<PackIconFontAwesomeKind>).Data);
else if (value is PackIconMaterial)
geoDrawing.Geometry = Geometry.Parse((value as PackIcon<PackIconMaterialKind>).Data);
else if (value is PackIconMaterialLight)
geoDrawing.Geometry = Geometry.Parse((value as PackIcon<PackIconEntypoKind>).Data);
else if (value is PackIconModern)
geoDrawing.Geometry = Geometry.Parse((value as PackIcon<PackIconMaterialLightKind>).Data);
else if (value is PackIconEntypo)
geoDrawing.Geometry = Geometry.Parse((value as PackIcon<PackIconEntypoKind>).Data);
else if (value is PackIconOcticons)
geoDrawing.Geometry = Geometry.Parse((value as PackIcon<PackIconOcticonsKind>).Data);
var drawingGroup = new DrawingGroup { Children = { geoDrawing }, Transform = new ScaleTransform(1, -1) };
return new DrawingImage { Drawing = drawingGroup };
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
然后使用转换器:
将命名空间添加到您的 .xaml 文件中:
xmlns:converters="clr-namespace:MyProject.Converters"
然后将图标显示为图像:
<Image Source="{Binding Source={icons:PackIconMaterial sitemap},
Converter={converters:PackIconToImageConverter},
ConverterParameter={StaticResource TextBrush}}"/>
或者要在用户控件或自定义控件中使用依赖属性,请将以下内容添加到您的控件中:
/// <summary>
/// Identifies the <see cref="Icon"/> dependency property.
/// </summary>
public static readonly DependencyProperty IconProperty = DependencyProperty.Register(nameof(Icon), typeof(object), typeof(MyControl), new PropertyMetadata(null));
/// <summary>
/// Gets or sets a value that specifies an user specific object which can be used as icon.
/// </summary>
public object Icon {
get { return GetValue(IconProperty); }
set { SetValue(IconProperty, value); }
}
然后绑定到属性,在你的模板中添加:
<ControlTemplate x:Key="MyControlTemplate" TargetType="{x:Type local:MyControl}">
<Image Source="{TemplateBinding Icon,
Converter={StaticResource IconPackConverter},
ConverterParameter={StaticResource TextBrush}}" />
</ControlTemplate>
【讨论】:
为什么需要在图像中使用它?图标是在自定义控件中呈现为字体的 SVG 资产。除非您尝试做一些特别高级的事情,否则您可以简单地删除<Image> 标签并直接使用<iconPacks:PackIconMaterial /> 控件,如here 所示。
【讨论】:
我在github上找到了一个更好的解决方案,关于代码的更多解释是here
您可以通过转换器将其转换并像这样在XAML 中使用
ImageSource="{Binding Source={x:Static
iconPacks:PackIconEntypoKind.AddToList}, Converter=
{converters:PackIconEntypoImageSourceConverter}, ConverterParameter=
{StaticResource TextBrush}}"
转换器代码是
/// <summary>
/// Converts a <see cref="PackIcon{TKind}" /> to an ImageSource.
/// Use the ConverterParameter to pass a Brush.
/// </summary>
public abstract class PackIconImageSourceConverterBase<TKind> : MarkupExtension, IValueConverter
{
/// <summary>
/// Gets or sets the thickness to draw the icon with.
/// </summary>
public double Thickness { get; set; } = 0.25;
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (!(value is TKind))
return null;
var foregroundBrush = parameter as Brush ?? Brushes.Black;
return CreateImageSource(value, foregroundBrush, Thickness);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
protected abstract ImageSource CreateImageSource(object value, Brush foregroundBrush, double penThickness);
}
/// <summary>
/// Converts a <see cref="PackIcon{TKind}" /> to an ImageSource.
/// Use the ConverterParameter to pass a Brush.
/// </summary>
public class PackIconImageSourceConverter : MarkupExtension, IValueConverter
{
/// <summary>
/// Gets or sets the thickness to draw the icon with.
/// </summary>
public double Thickness { get; set; } = 0.25;
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is null)
return null;
if (value is PackIconFontAwesomeKind)
return new PackIconFontAwesomeImageSourceConverter { Thickness = Thickness }.Convert(value, targetType, parameter, culture);
if (value is PackIconMaterialKind)
return new PackIconMaterialImageSourceConverter { Thickness = Thickness }.Convert(value, targetType, parameter, culture);
if (value is PackIconMaterialLightKind)
return new PackIconMaterialLightImageSourceConverter { Thickness = Thickness }.Convert(value, targetType, parameter, culture);
if (value is PackIconModernKind)
return new PackIconModernImageSourceConverter { Thickness = Thickness }.Convert(value, targetType, parameter, culture);
if (value is PackIconEntypoKind)
return new PackIconEntypoImageSourceConverter { Thickness = Thickness }.Convert(value, targetType, parameter, culture);
if (value is PackIconOcticonsKind)
return new PackIconOcticonsImageSourceConverter { Thickness = Thickness }.Convert(value, targetType, parameter, culture);
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
public class PackIconEntypoImageSourceConverter : PackIconImageSourceConverterBase<PackIconEntypoKind>
{
protected override ImageSource CreateImageSource(object value, Brush foregroundBrush, double penThickness)
{
var packIcon = new PackIconEntypo { Kind = (PackIconEntypoKind)value };
var geometryDrawing = new GeometryDrawing
{
Geometry = Geometry.Parse(packIcon.Data),
Brush = foregroundBrush,
Pen = new Pen(foregroundBrush, penThickness)
};
var drawingGroup = new DrawingGroup { Children = { geometryDrawing }, Transform = new ScaleTransform(1, -1) };
return new DrawingImage { Drawing = drawingGroup };
}
}
public class PackIconFontAwesomeImageSourceConverter : PackIconImageSourceConverterBase<PackIconFontAwesomeKind>
{
protected override ImageSource CreateImageSource(object value, Brush foregroundBrush, double penThickness)
{
var packIcon = new PackIconFontAwesome { Kind = (PackIconFontAwesomeKind)value };
var geometryDrawing = new GeometryDrawing
{
Geometry = Geometry.Parse(packIcon.Data),
Brush = foregroundBrush,
Pen = new Pen(foregroundBrush, penThickness)
};
var drawingGroup = new DrawingGroup { Children = { geometryDrawing }, Transform = new ScaleTransform(1, -1) };
return new DrawingImage { Drawing = drawingGroup };
}
}
public class PackIconMaterialImageSourceConverter : PackIconImageSourceConverterBase<PackIconMaterialKind>
{
protected override ImageSource CreateImageSource(object value, Brush foregroundBrush, double penThickness)
{
var packIcon = new PackIconMaterial { Kind = (PackIconMaterialKind)value };
var geometryDrawing = new GeometryDrawing
{
Geometry = Geometry.Parse(packIcon.Data),
Brush = foregroundBrush,
Pen = new Pen(foregroundBrush, penThickness)
};
var drawingGroup = new DrawingGroup { Children = { geometryDrawing } };
return new DrawingImage { Drawing = drawingGroup };
}
}
public class PackIconMaterialLightImageSourceConverter : PackIconImageSourceConverterBase<PackIconMaterialLightKind>
{
protected override ImageSource CreateImageSource(object value, Brush foregroundBrush, double penThickness)
{
var packIcon = new PackIconMaterialLight { Kind = (PackIconMaterialLightKind)value };
var geometryDrawing = new GeometryDrawing
{
Geometry = Geometry.Parse(packIcon.Data),
Brush = foregroundBrush,
Pen = new Pen(foregroundBrush, penThickness)
};
var drawingGroup = new DrawingGroup { Children = { geometryDrawing } };
return new DrawingImage { Drawing = drawingGroup };
}
}
public class PackIconModernImageSourceConverter : PackIconImageSourceConverterBase<PackIconModernKind>
{
protected override ImageSource CreateImageSource(object value, Brush foregroundBrush, double penThickness)
{
var packIcon = new PackIconModern { Kind = (PackIconModernKind)value };
var geometryDrawing = new GeometryDrawing
{
Geometry = Geometry.Parse(packIcon.Data),
Brush = foregroundBrush,
Pen = new Pen(foregroundBrush, penThickness)
};
var drawingGroup = new DrawingGroup { Children = { geometryDrawing } };
return new DrawingImage { Drawing = drawingGroup };
}
}
public class PackIconOcticonsImageSourceConverter : PackIconImageSourceConverterBase<PackIconOcticonsKind>
{
protected override ImageSource CreateImageSource(object value, Brush foregroundBrush, double penThickness)
{
var packIcon = new PackIconOcticons { Kind = (PackIconOcticonsKind)value };
var geometryDrawing = new GeometryDrawing
{
Geometry = Geometry.Parse(packIcon.Data),
Brush = foregroundBrush,
Pen = new Pen(foregroundBrush, penThickness)
};
var drawingGroup = new DrawingGroup { Children = { geometryDrawing } };
return new DrawingImage { Drawing = drawingGroup };
}
}
【讨论】:
我已成功使用以下仅限 XAML 的解决方案:
<ContentControl Margin="10,2" Background="Blue" Foreground="White"
Content="{iconPacks:Material Kind=GestureTap}"
ToolTip="This is a tooltip"
IsEnabled="{Binding ShouldThisBeEnabled}"
Visibility="{Binding ShouldThisBeVisible, Converter={StaticResource VisibilityFromBool}}" />
【讨论】:
也许我来得太晚了,但我正在努力。 我认为有时解决方案可能更容易 在您的 xaml 页面上创建此 xmlns:
xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
然后……
<Image Source="{Binding Source={iconPacks:BootstrapIconsImage Kind=Upload}}"/>
然后图像就会显示出来。
享受编码
【讨论】: