How to reuse a static GeometryDrawing in a DrawingImage using xaml - c#

If I define in app.xaml a GeometryDrawing like this:
<GeometryDrawing x:Key="ReuseThis"
Pen="..."
Brush="..."
Geometry="..."/>
How can I then use it later in a DrawingImage like this:
<DrawingImage x:Key="FullImage">
<DrawingImage.Drawing>
<DrawingGroup>
<GeometryDrawing reuse it here somehow"{StaticResource ReuseThis}"/>
<Geometrydrawing ...>
<Geometrydrawing ...>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
I'm trying to avoid copying and pasting that GeometryDrawing in a bunch of DrawingImages I have.
Thanks

You can use the StaticResource Markup Extension in XAML Object Element Syntax:
<DrawingImage>
<DrawingImage.Drawing>
<DrawingGroup>
<StaticResource ResourceKey="ReuseThis"/>
<GeometryDrawing .../>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>

Related

Referencing whole class from resource dictionary

I've created a resource dictionary with multiple classes
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Something_GUI">
<PathGeometry x:Key="DeleteIcon" Figures="M93.05,47.59A2.08,2.08,0,0,0,91,45.51a2,2,0,0,0-.68.13h0l0,0-.1,0C82.9,48.24,70,51.13,
48.58,51.13c-20.27,0-32.93-2.59-40.37-5a2.28,2.28,0,0,0-.83-.17,2.07,2.07,0,0,0-2,1.82l0,.06,
4.87,76.56c0,3.17,2.82,4.8,3.93,5.43,1.4.82,6.74,6.15,35.08,6.15s33.68-5.33,35.08-6.15c1.11-.63,
3.93-2.26,3.93-5.43L93.05,47.8l0,0C93,47.72,93.05,47.65,93.05,47.59ZM48.42,80a5.59,5.59,0,1,1-5.59,
5.59A5.59,5.59,0,0,1,48.42,80ZM32.24,118a5.59,5.59,0,1,1,5.59-5.59A5.59,5.59,0,0,1,32.24,118ZM34.6...
Now in another XAML Page I've merged my ResourceDictionary and I'm trying to draw this icon using the following code
<DrawingImage>
<DrawingImage.Drawing>
<GeometryDrawing >
<GeometryDrawing.Geometry>
<PathGeometry/>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingImage.Drawing>
</DrawingImage>
My intention is to use the PathGeometry that I've already defined inside my ResourceDictionary.xaml but I haven't found a way to reference this. I can't call <PathGeometry Figures="{StaticResource myIcon}" nor I find something like <GeometryDrawing.Geometry Data={} /> or <GeometryDrawing.Geometry PathGeometry={} /> that I could use to reference directly the object I'm trying to use. I've googled the topic but haven't found any answers yet.
Is there a way to reference a whole object from the resource dictionary?
It is as simple as this:
<DrawingImage>
<DrawingImage.Drawing>
<GeometryDrawing
Geometry="{StaticResource DeleteIcon}"
Brush="Black" />
</DrawingImage.Drawing>
</DrawingImage>

Using Vector images as an image source. WPF , C#

i'm working on a project including loads of images. the thing is, like the title says, i have to convert all my vector images to png before i can use them as a image source.
I have vector images created in illustrator. I have them in the .ai project file , how do i go from here ?
My goal is to be able to do this :
<Image Width="70" Height="70" Source="MyVectorImage"/>
If you want to get the ImageSource from a geometry path image into your cs file, you can put the drawingImage into a resource file: Icons.xaml:
<DrawingImage x:Key="hazelnut">
<DrawingImage.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="Black">
<GeometryDrawing.Geometry>
<GeometryGroup>
<PathGeometry Figures="M 16.6309,18.6563C 17.1309,8.15625 29.8809,14.1563 29.8809,14.1563C 30.8809,11.1563 34.1308,11.4063 34.1308,11.4063C 33.5,12 34.6309,13.1563 34.6309,13.1563C 32.1309,13.1562 31.1309,14.9062 31.1309,14.9062C 41.1309,23.9062 32.6309,27.9063 32.6309,27.9062C 24.6309,24.9063 21.1309,22.1562 16.6309,18.6563 Z M 16.6309,19.9063C 21.6309,24.1563 25.1309,26.1562 31.6309,28.6562C 31.6309,28.6562 26.3809,39.1562 18.3809,36.1563C 18.3809,36.1563 18,38 16.3809,36.9063C 15,36 16.3809,34.9063 16.3809,34.9063C 16.3809,34.9063 10.1309,30.9062 16.6309,19.9063 Z ">
<PathGeometry.Transform>
<TransformGroup>
<ScaleTransform
CenterX="23"
CenterY="20"
ScaleX="0.45"
ScaleY="0.45" />
</TransformGroup>
</PathGeometry.Transform>
</PathGeometry>
</GeometryGroup>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
And add in you App.xaml:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Resources/Icons.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
And use it in your cs file like:
ImageSource image = ResourcePathToImageSource("hazelnut");
private ImageSource ResourcePathToImageSource(string resourcesName)
{
return (DrawingImage)Application.Current.TryFindResource(resourcesName);
}
You can use a DrawingImage as the Image's Source. DrawingImage uses a Geometry (i.e. vector graphics) instead of a bitmap.
<Image>
<Image.Source>
<DrawingImage>
<DrawingImage.Drawing>
<GeometryDrawing>
<GeometryDrawing.Pen>
<Pen Thickness="2" Brush="Black"/>
</GeometryDrawing.Pen>
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="100,100,100,100"/>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingImage.Drawing>
</DrawingImage>
</Image.Source>
</Image>
You can of course also bind the Source property to a view model property of type ImageSource, which contains a DrawingImage that you would create from your original vector data.

Best way to use a vector image in Viewport3D?

I was able to display a vector image with standard WPF like this.
<Image >
<Image.Source>
<DrawingImage>
<DrawingImage.Drawing>
<GeometryDrawing>
<GeometryDrawing.Pen>
<Pen Brush="#8F8E8F" Thickness="1" />
</GeometryDrawing.Pen>
<GeometryDrawing.Geometry>
<LineGeometry StartPoint="0,0" EndPoint="0,10"/>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingImage.Drawing>
</DrawingImage>
</Image.Source>
</Image>
Unfortunately I was not able to do the same inside a Viewport3D element.
I created a VisualBrush from the Image and added it to the DiffuseMaterial of my 3D Model.
I also tried it via a DrawingBrush. Unfortunately the vector image gets renderd to a standard bitmap at some point of the pre-render processed. (that is what i think).
Is it even possible to display a vector image inside a Viewport3D?
Thank you for help in advance.

Set InkCanvas Background DrawingBrush via C#

I want to set the following XAML attributes via C#:
<InkCanvas.Background>
<DrawingBrush Stretch="None" TileMode="Tile" Viewport="0,0,2,2" ViewportUnits="Absolute">
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="White">
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0,0,2,2" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFE3E3E3">
<GeometryDrawing.Geometry>
<GeometryGroup>
<RectangleGeometry Rect="0,0,1,1" />
<RectangleGeometry Rect="1,1,1,1" />
</GeometryGroup>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</InkCanvas.Background>
How should I go about this?
I have found the solution myself and leave it here for anyone else, facing the same issue.
http://www.c-sharpcorner.com/uploadfile/mahesh/wpf-drawing-brush/ pretty much is what i was looking for.

How to use DrawingBrush as Window.Icon?

I have a DLL that has a ResourceDictionary containing a XAML image:
<DrawingBrush x:Key="imgFoo" ViewboxUnits="Absolute" Viewbox="0,0,128,128">
<DrawingBrush.Drawing>
<GeometryDrawing Brush="#FF111111">
<GeometryDrawing.Pen>
<Pen LineJoin="Miter" StartLineCap="Square" EndLineCap="Square"/>
</GeometryDrawing.Pen>
<GeometryDrawing.Geometry>
<PathGeometry Figures="M 56.5625 ... 64.03125 45.46875 z"
FillRule="NonZero"/>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
Is it possible to use this DrawingBrush as Window.Icon?
using StaticResource or DynamicResource doesn't work:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Icon="{DynamicResource imgFoo}">
The only thing I found is using Window.Resources like this:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Icon="{DynamicResource imgFoo}">
<Window.Resources>
<DrawingImage x:Key="imgFoo">
<DrawingImage.Drawing>
<GeometryDrawing Brush="#FF111111">
<GeometryDrawing.Pen>
<Pen LineJoin="Miter" StartLineCap="Square"
EndLineCap="Square"/>
</GeometryDrawing.Pen>
<GeometryDrawing.Geometry>
<PathGeometry Figures="M 56.5625 ... 64.03125 45.46875 z"
FillRule="NonZero"/>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingImage.Drawing>
</DrawingImage>
</Window.Resources>
But this uses only a part of the DrawingBrush from the DLL file and creates duplicate XAML code.
Any suggestions on how I could use that DrawingBrush directly?
You could split the resource declaration into two parts and declare the GeometryDrawing and the DrawingBrush separately:
<GeometryDrawing x:Key="imgFooDrawing" Brush="#FF111111">
<GeometryDrawing.Pen>
<Pen LineJoin="Miter" StartLineCap="Square" EndLineCap="Square"/>
</GeometryDrawing.Pen>
<GeometryDrawing.Geometry>
<PathGeometry Figures="M10,64 L64,10 118,64 64,118Z" FillRule="NonZero"/>
</GeometryDrawing.Geometry>
</GeometryDrawing>
<DrawingBrush x:Key="imgFoo" ViewboxUnits="Absolute" Viewbox="0,0,128,128"
Drawing="{StaticResource imgFooDrawing}">
</DrawingBrush>
Now you could directly reuse the GeometryDrawing in a DrawingImage that is used as the Window's Icon:
<Window.Icon>
<DrawingImage Drawing="{DynamicResource imgFooDrawing}"/>
</Window.Icon>
In case you can't change the Resource DLL, you could bind the DrawingImage's Drawing property to the Drawing property of the DrawingBrush.
This would however require an ugly workaround because you can't use a DynamicResource as binding source. You may set the Tag property of the Window to the DrawingBrush, and then create a RelativeSource/FindAncestor binding:
<Window ... Tag="{DynamicResource imgFoo}">
<Window.Icon>
<DrawingImage Drawing="{Binding Tag.Drawing,
RelativeSource={RelativeSource AncestorType=Window}}"/>
</Window.Icon>
</Window>

Categories