Using XAML vector graphics in WPF application - wpf

I have a vector image that I've defined in XAML. What is the proper way to use this resource in a WPF application?
I want to have the vector image in its own XAML file, and then add the image to other UserControls in my application. What should be the top-level element in my XAML vector image? How do I refer to that image in other UserControls?

http://learnwpf.com/post/2006/06/04/How-do-I-Include-Vector-Based-Image-Resources-in-my-WPF-Application.aspx explains how to do it.
<ContentControl Template="{StaticResource Credit-Card}" />

It is extremely difficult to use vector graphics in a reusable way in WPF and Silverlight.
These two StackOverflow questions discuss some of the options available:
XAML Icons - How to use?
WPF What is the correct way of using SVG files as icons in WPF
After reading through these questions and answers, I think the best solution is to stick with with a bitmap/raster format like PNG until Microsoft decides to support SVG.

Here's how to do it in a reusable style-able way:
https://github.com/alansingfield/VectorIcon/blob/master/README.md
<Style x:Key="CarIcon"
TargetType="local:VectorIcon">
<Style.Setters>
<Setter Property="Geometry">
<Setter.Value>
<PathGeometry Figures="M18,18H6V6H18M18,4H6A2,2 0 0,0 4,6V18A2,2 0 0,0 6,20H18A2,2 0 0,0 20,18V6C20,4.89 19.1,4 18,4Z" />
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
<local:VectorIcon Style="{StaticResource CarIcon}" Foreground="Green"/>

Related

Any examples of a rich visual behaviour WPF button?

I am looking for an example of a customized WPF button.
Ideally in a liked Blend/VS2013 configuration, i.e. a VS2013 test solution that includes a button project that can be edited in Blend for VS2013.
The button should have a visual appearance that makes it clear what state it is in, i.e.
Normal = default
MouseOver = inner glow
Pressed = smaller size / smaller shadow
ToggledOn = outer glow
Disabled = grayed out
Given such an example I could then just tweak the visual appearance of the states using Blend.
And on the application side I want to just instantiate the button, associate the style, and set properties for BackgroundColor, image/icon, text label, width, height.
I seems that using a ControlTemplate style is the recommended way of doing this, rather than sub-classing, see MSDN.
The three key issues seem to be:
how to setup the VS2013/blend project structure to use both interchangeably on a single set of source files
how to compute relative sizes in the ControlTemplate, i.e. what is the syntax for
Width = Button.Width x 1.1 to set a glow extend relative to the actual button size that is not in the template, but to be defined on the client application UI design.
how to compute relative colors from the base color of the button, i.e. what is the WPF XAML syntax for GradientStop Color = Button.BackgroundColor x 80% + White x 20%
This should be a very common need, but Google was not helpful in finding anything like the above.
Any help with any one of the three key issues would be greatly appreciated.
Your requirements do not require defining a new ControlTemplate and can be achieved with a Style with Triggers, e.g.:
<Grid>
<Grid.Resources>
<Style TargetType="Button">
<Setter Property="RenderTransformOrigin" Value="0.5,0.5"/>
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="RenderTransform">
<Setter.Value>
<ScaleTransform ScaleX="0.75" ScaleY="0.75"/>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<Button Content="Click Me!" />
</Grid>
The Style can be accessible anywhere in the application if defined in your App.xaml Resources and given an x:Key
Using ScaleTransform's ScaleX and ScaleY are relative values.
You will need your own IValueConverter then bind the target color to a source color using your converter.

Can you programmatically set a property in a ControlTemplate from a ChildWindow?

I am working on a Silverlight application that has resource files that define styles for the different types of Child Windows in the application. The <Style> contains <ControlTemplate> markup with various content. Is there a way to set one of the properties of the controls defined within the <ControlTemplate> from the Child Window's class?
For example, imagine in the resource file I have markup like the following:
<Style x:Key="MyChildWindowStyle" TargetType="sdk:ChildWindow">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="sdk:ChildWindow">
<Grid x:Name="Root">
...
<Image Source="/Assets/image.png" />
...
</Grid>
</ContentTemplate>
</Setter>
</Style>
Now assume that I have a number of child windows that are configured to use this style. What I'd like to be able to do is from the code in those child windows be able to programmatically change the value of the image's Source.
Is this possible?
Thanks
In your resources you can do this:
<BitmapImage x:Key="MyImage" Source="/Assets/image.png"/>
<Style x:Key="MyChildWindowStyle" TargetType="sdk:ChildWindow">
...
<Image Source="{DynamicResource MyImage}" />
...
</Style>
Then in your child window's code-behind you can do this:
Resources["MyImage"] = new BitmapImage(new Uri("/Assets/other-image.png"));
But if your child window class is in another assembly you should be writing the uri a bit different:
Resources["MyImage"] = new BitmapImage(new Uri("pack://application:,,,/MyOtherAssemblyShortName;component/Assets/other-image.png"));
You can check msdn page for package uri format.
But I suggest you to use MVVM pattern in order to get most out of WPF in terms of bindings, styling etc. When you have a view model instead of a code-behind these things become simpler. You may wanna check the related msdn page, a codeproject sample, a toolkit or a validation mechanism designed for MVVM.
#zahir's answer pointed me in the right direction, but to get it to work in Silverlight I had to do the following:
First, I added the <BitmapImage> markup to my resource file, using the UriSource property to specify the default value.
<BitmapImage x:Key="MyImage" UriSource="../Assets/DefaultImage.png" />
Next, I referenced it in the <ControlTemplate> like so:
<Image ... Source="{StaticResource MyImage}"/>
Then, in my code-behind class I was able to modify the UriSource property like so:
BitmapImage img = (Application.Current.Resources["MyImage"] as BitmapImage);
if (img != null)
img.UriSource = "../Assets/NewImage.png";
Of course, the precise values for UriSource would depend on how you are handling image assets, where they are located, etc.

How to reuse icons (xaml-paths) in a large project?

I am part of the development of a larger-scale Silverlight 4 project, where we will have a set of symbols that should be used across different parts of the GUI (see the example below).
These icons are made from multiple paths directly in Blend, and will be used, either singly or as different visual states in usercontrols (with the same icon used in more than one context). In order to facilitate changing the design of a single icon, and having it propagate throughout the application, what is the best way to store these?
I have tried creating styles from them (right click -> edit style..), but this only allows me to create an empty style, without any path data. manually putting the xaml code for the grid containing the paths into a dictionary hasn't helped either, what am I missing?
How do I save the path and style (colour, stroke, fill, etc) information in an easy way, preferably in a resource dictionary, so I can easily reuse them in usercontrols and elsewhere, while maintaining the easy updating?
Example of the icons I'm trying to reuse:
<Style x:Key="MyIcon" TargetType="ContentControl">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Path Stretch="Fill" Fill="Red" Data="F1 M 24,13C 27.1521,13 29.9945,14.3258 32,16.4501L 32,11L 35,14L 35,22L 27,22L 24,19L 29.5903,19C 28.217,17.4656 26.2212,16.5 24,16.5C 20.1969,16.5 17.055,19.3306 16.5661,23L 13.0448,23C 13.5501,17.3935 18.262,13 24,13 Z M 24,31.5C 27.8031,31.5 30.945,28.6694 31.4339,25L 34.9552,25C 34.4499,30.6065 29.738,35 24,35C 20.8479,35 18.0055,33.6742 16,31.5499L 16,37L 13,34L 13,26L 21,26L 24,29L 18.4097,29C 19.783,30.5344 21.7787,31.5 24,31.5 Z "/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
And then use style with contentcontrol type (or derivates):
<ContentControl Style="{StaticResource MyIcon}" Width="20" Height="20" Grid.Row="0"/>
All styles can be inside some resource dictionary:
This is quite informative article:
http://blogs.infosupport.com/tips-for-effective-usage-of-resource-dictionaries-in-silverlight-and-wpf/

How to center text around point using xaml

I would like to be able to place the word "hello" centered on a specific point. I need to do this completely in XAML without extra code. Best I can tell, all the text alignment properties/styles in XAML act on text within some bounding canvas or other element.
Since I don't know the length of the text I want to center, I can't center it using my own code.
The reason I need to solve the problem entirely in XAML is that I'm not using WPF to create the XAML, I'm writing it directly to an XML DOM. It will then be loaded into a Silverlight or WPF control for display.
In most graphic languages, including SVG, which is where my code originated, text can be aligned against a "stationary point" without a bounding box.
Any suggestions appreciated
(Yes, I know this question is old.)
The effectiveness of this solution may vary with the version of Silverlight or the .NET Framework you are using, and I haven't tried it with Silverlight for Windows Phone 7. I wrote a version for stand-alone WPF applications, and I wrote another version that also works in Silverlight.
First, the version that works in Silverlight and WPF. Please note that you will need to refactor the code a little bit if you aren't using a Canvas to provide an absolute position for the center of your TextBlock. For example, you may be using a TranslateTransform to position your text.
<Canvas>
<Canvas.Resources>
<ScaleTransform x:Key="transform" ScaleX="-1" ScaleY="-1" />
</Canvas.Resources>
<Grid RenderTransform="{StaticResource transform}" RenderTransformOrigin="-.25 -.25">
<TextBlock RenderTransform="{StaticResource transform}">
Hello!
</TextBlock>
</Grid>
</Canvas>
Second, the version that works only in WPF. It doesn't work in Silverlight because it depends on the presence of the Canvas.Right and Canvas.Bottom attached properties. UniformGrid isn't in Silverlight either, but that code could have been replaced by a regular Grid with 2 star-length rows and columns.
<Canvas>
<UniformGrid Rows="2" Columns="2"
DataContext="{Binding ElementName=textBox1}"
Width="{Binding Path=ActualWidth}"
Height="{Binding Path=ActualHeight}">
<Canvas>
<TextBlock Name="textBox1" Canvas.Right="0" Canvas.Bottom="0">
Hello!
</TextBlock>
</Canvas>
</UniformGrid>
</Canvas>
By the way, there may be more efficient ways to solve this problem available. I am making no guarantees!

Scaling/resizing the diameter of all bubbles on a bubble chart (in WPF or Silverlight)

I have a bubble chart in a WPF application with LOTS of points in a BubbleSeries. The automatically drawn sizes of the bubbles result in so much overlap of the plotted bubbles, that most of the bubble points are obscured. The drawn bubble size does not change if I alter the data reduce the SizeValues of all the plotted points (some sort of hidden logic seems to be determining how to automatically scale the SizeValues when drawing the bubbles).
How can I reduce the diameter of every bubble by 75% (so each bubble's diameter is one fourth the normal automatic size)?
Thanks, Alan
[I am working with the charting/data visulaization controls in the June 2009 WPF control toolkit, but I think the same question and answer probably applies to Silverlight 3 bubble charts.]
Creating the Style:
<Style x:Key="BubbleDataPointStyle" TargetType="chartingToolkit:BubbleDataPoint">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="chartingToolkit:BubbleDataPoint">
<Grid RenderTransformOrigin=".5,.5">
<Grid.RenderTransform>
<ScaleTransform ScaleX=".25" ScaleY=".25" />
</Grid.RenderTransform>
<controlsToolkit:Viewbox x:Name="viewbox">
<Ellipse Width="1" Height="1" />
</controlsToolkit:Viewbox>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Add the Style to your data points:
<chartingToolkit:Chart>
<chartingToolkit:Chart.Series>
<chartingToolkit:BubbleSeries
ItemsSource="{Binding ObjectCollection}"
IndependentValuePath="AxisX"
DependentValuePath="AxisY"
SizeValuePath="Size"
DataPointStyle="{StaticResource BubbleDataPointStyle}" />
</chartingToolkit:Chart.Series>
</chartingToolkit:Chart>
If I understand the question correctly, you want to be able to scale your content without actually having to redraw it, correct? If so, you should have a look at the Viewbox class.
Not sure if there's something like this in WPF toolkit charts but in amCharts for WPF there are MinBulletSize/MaxBulletSize properties to control scaling of the bubbles. I think there must be something along these lines in WPF/Silverlight toolkit charts too.

Resources