Использование файла XAML в качестве векторного источника изображения

Я хотел бы иметь возможность использовать векторную графику, предпочтительно определенную в XAML, как элемент управления Source of Image, так же, как я могу в настоящее время использовать растровое изображение, такое как PNG. Таким образом, я мог легко смешивать и сопоставлять между растровым и векторным изображениями, например:

<StackPanel>
    <Image Source="Images/Namespace.png"/>
    <Image Source="Images/Module.xaml"/>
</StackPanel>

Module.xaml скорее всего имеет <DrawingImage> как его корневой элемент вместо <UserControl>.

Вообще-то, что я действительно делаю, это так, поэтому моя ViewModel может выбрать растровое или векторное изображение по своему усмотрению:

<Image Source="{Binding ImageUri}"/>

Возможно ли это? Может ли Image.Source загружать классы XAML из заданного URI? Или он может загружать только растровые ресурсы?

Ответы

Ответ 1

Вы можете просто ссылаться на свою векторную графику как на StaticResources:

<Image Source="{StaticResource MyImage}" />

Храните изображения в ResourceDictionary как DrawImage. Expression Blend может помочь вам создать этот материал:

<ResourceDictionary
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

   <DrawingImage x:Key="MyImage">
      <DrawingImage.Drawing>
         <DrawingGroup>
            <DrawingGroup.Children>
               <GeometryDrawing Brush="Black" Geometry="M 333.393,... 100.327 Z "/>
               <GeometryDrawing Brush="Black" Geometry="F1 M 202.309,... Z "/>
                      :
            </DrawingGroup.Children>
         </DrawingGroup>
     </DrawingImage.Drawing>
   </DrawingImage>

</ResourceDictionary>

Ответ 2

1) Добавьте DrawingImage.xaml в проект и установите его свойства в "BuildAction = Content" и "Copy Always". Или вы можете динамически загружать XAML извне, поскольку логика, которую я собираюсь объяснить, будет работать и для free-xaml.

2) Запишите конвертер для преобразования XAML uri в UIELement, в вашем случае это будет всегда DrawingImage

public class FileToUIElementConverter :IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        FileStream fileStream = new FileStream((string)parameter, FileMode.Open); 
        return XamlReader.Load(fileStream) as DrawingImage;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

3) Напишите XAML, как показано ниже

<Window.Resources>
    <local:FileToUIElementConverter x:Key="uriToUIElementConverter"/>
</Window.Resources>
<Grid>
    <Image Stretch="Fill" Source="{Binding Converter={StaticResource uriToUIElementConverter},ConverterParameter=ImageDrawing.xaml}"/>
</Grid>

Ответ 3

Вставьте ресурс XAML (DrawingImage) с типом "Ресурс". Это не отдельный файл и может быть напрямую привязан через URI, как в вашем исходном примере - НО URI является нетривиальным. Вы должны выяснить синтаксис URI Microsoft "pack" и использовать его.