Using a XAML file as a vector Image Source

社会主义新天地 提交于 2019-12-28 03:53:05

问题


I would like to be able to use vector graphics, preferably defined in XAML, as the Source of an Image control, just like I can currently use a raster image like a PNG. That way I could easily mix and match between bitmap and vector images, like this:

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

Module.xaml would most likely have <DrawingImage> as its root element instead of <UserControl>.

Actually, what I'm really going for is this, so my ViewModel could select either a raster or vector image at its discretion:

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

Is this possible? Can Image.Source load XAML classes from a given URI? Or is it only able to load bitmap resources?


回答1:


You can simply reference your vector graphics as StaticResources:

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

Store the images in a ResourceDictionary as DrawImage's. Expression Blend can help you generate this stuff:

<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) Add the DrawingImage.xaml to the project and set its properties to 'BuildAction=Content' and 'Copy Always'. Or else you can dynamically load the XAML from outside since the logic I am going to explain will work for loose-xaml also.

2) Write a Converter to convert the XAML uri to UIELement, in your case it will be always 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) Write the XAML as below

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



回答3:


Embed the XAML resource (DrawingImage) with type 'Resource'. It is then not a separate file and can be directly referenced via a URI, as in your original example -- BUT the URI is non-trivial. You have to figure out Microsoft's "pack" URI syntax and use that.



来源:https://stackoverflow.com/questions/1107334/using-a-xaml-file-as-a-vector-image-source

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!