使用MarkupExtension以xaml

时间:2016-01-20 09:45:50

标签: wpf xaml resources markup

我有一个资源(.resx),其中包含svg图像的日志。此外,我使用一个ImageResource类,它可以获取资源提供的byte []并将其转换为ImageSource对象。 在这样做时,我可以更改图标的颜色

ImageResource.CreateFromSvg(image, Brushes.Green);

我正在寻找一种将这些图像放入xaml的简单方法,因此我创建了另一个使用ImageResource类创建Image的静态类。在xaml我可以使用

<Image Source={x:Static img:ImageResources.MyGreenIcon}/>

获取图标。缺点是,我无法选择xaml中的颜色。所以我尝试为此创建了一个 MarkupExtension 。它需要 byte [] Brush 作为参数,调用 CreateFromSvg -Method并返回Image。在Xaml中它看起来像这样

<Image Source={i:Img {x:Static img:SvgResources.TheIcon}, Green}/>

其中SvgResources是Image所在的.resx文件。 虽然这很好用,但我无法在运行时更改颜色。因为MarkupExtension不是DependencyProperty,所​​以我不能使用绑定颜色。我试图使用触发器

<Style TargetType="{x:Type Image}">
    <Style.Triggers>
      <Trigger Property="IsMouseOver" Value="true">
        <Setter Property="Source" Value="{i:Img {x:Static img:SvgResources.TheIcon}, Blue}" />
      </Trigger>
    </Style.Triggers>
</Style>

这不会给出任何错误,但什么都不做。所以我的问题是

  1. 如何重新分配图像来源以获得另一种颜色
  2. 有没有办法使用类似绑定的东西来改变VM的颜色
  3. 有没有办法将{x:Static img:SvgResources.TheIcon缩短为svgResource.TheIcon
  4. 修改

    我发现,如果我没有在控件本身设置源,触发器会更改源,而是在触发器中提供默认值(IsMouseOver = false)。问题2 + 3仍然存在

1 个答案:

答案 0 :(得分:0)

回答问题2。

您可以将MarkupExtension扩展为支持Binding的{​​{1}}。

创建简单的MultiValueConverter,它将简单地调用您的MultiValueConverter。传递给此转换器的值将是图像和ImageResource.CreateFromSvg(...);(通过绑定解析的静态图像或画笔)

Brush中检测传递的值ProvideValue(...)Brush。如果是Binding,则用此Brush作为Binding为其创建模拟Brush。 如果值为Source-我们将使用它。对图像执行相同的操作

创建Binding,分配刚创建的Multibinding并添加图像和画笔绑定。

MultiValueConverter提供了价值。

完整的Img MarkupExtension示例:

return

用法示例:

public class Img : MarkupExtension
{
    private readonly object _image;
    private readonly object _brush;
    public Img(object image, object brush)
    {
        _image = image;
        _brush = brush;
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        var imageBinding = _image is Binding iBinding ? iBinding : new Binding { Source = _image};
        var brushBinding = _brush is Binding bBinding ? bBinding : new Binding { Source = _brush };

        var binding = new MultiBinding
        {
            Converter = new ImgValueConverter()
        };

        binding.Bindings.Add(imageBinding);
        binding.Bindings.Add(brushBinding);

        return binding.ProvideValue(serviceProvider);
    }

    private class ImgValueConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            var image = values[0];
            var brush = values[1];

            return ImageResource.CreateFromSvg(image, brush);
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}