How to change bitmap images to vector path's - xaml

In my Windows Phone 8 app I use set of icons. These icons are used multiple times with different size and colour. Right now I just have multiple png files from same icon to cover all these variants.
How this can he handled with vector images? My ultimate goal is to store vector path to e.g. resource file and use that as "image source", set image size and colour in my view, not in resource file.
Lets say I have Canvar like this:
<Canvas Width="76" Height="76" Clip="F1 M 0,0L 76,0L 76,76L 0,76L 0,0">
<Path Width="23.75" Height="49.4791" Canvas.Left="26.9167" Canvas.Top="13.8542" Stretch="Fill" Fill="#FF000000" Data="F1 M 26.9167,13.8542L 50.6666,13.8542L 50.6667,39.5833L 26.9167,63.3333L 26.9167,13.8542 Z "/>
</Canvas>
How I can store this to resource and use it as image source?
All suggestions and ideas are welcome how to handle this.
UPDATE
Based on Chris W answer, I came to this solution:
<Style x:Key="Marker" TargetType="ContentControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<Canvas Width="76" Height="76">
<Path Fill="{TemplateBinding Foreground}" Data="m 26.9167 13.8542 23.7499 0 10e-5 25.7291 -23.75 23.75 0 -49.4791 z"></Path>
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ContentControl Style="{StaticResource Marker}" Foreground="Red" />
This works ok, I can reuse the Mrker style and set it fill color. The missing piece in this is, how should I resize the canvas/contetnControl?
Now the canvas size is 76*76, even if I change that the output image still the same size. How should I resize the canvas?

The first part of your question would be a duplicate and I think Illustrator or other suites can do the same, but to answer your second question you can just make it into a ContentControl template like;
<Style x:Key="ReUsableResource" TargetType="ContentControl">
<Setter Property="Height" Value="49.4791"/>
<Setter Property="Width" Value="23.75"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<Canvas>
<Path Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" Stretch="Fill" Fill="#FF000000" Data="F1 M 26.9167,13.8542L 50.6666,13.8542L 50.6667,39.5833L 26.9167,63.3333L 26.9167,13.8542 Z "/>
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Then invoke it like;
<ContentControl Width="100" Height="50" Style="{StaticResource ReUsableResource}"/>
Oh and just read the comments, to get it from Vector to XAML another really handy resource is Mike Swanson's XAML exporter plugin for Illustrator.
Hope this helps.

Related

Custom control with text box and text block

I would like to build a validation text box, which would be a normal UWP TextBox wrapped within a StackPanel, which also contains a TextBlock. The intent is that a validation message can be shown beneath the text box when there is a validation error.
I know I can do this by creating a custom control, but this would require me to implement all the properties I need and create a bunch of dependency properties, etc.
I'm hoping there is an easier way, where I can just completely derive the text box, but override the display template for it and include a label beneath it.
You can get most of the way there in XAML using the built-in IDataErrorInfo-based validation machinery and defining a control template for the TextBox's Validation.ErrorTemplate. There's a pretty good article at this link:
The XAML from the article at the link above follows, also check out this discussion on WPF's built-in validation here.
<Style TargetType="{x:Type Label}">
<Setter Property="Margin" Value="5,0,5,0" />
<Setter Property="HorizontalAlignment" Value="Left" />
</Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Margin" Value="0,2,40,2" />
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<DockPanel LastChildFill="true">
<Border Background="OrangeRed" DockPanel.Dock="right" Margin="5,0,0,0"
Width="20" Height="20" CornerRadius="5"
ToolTip="{Binding ElementName=customAdorner,
Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
<TextBlock Text="!" VerticalAlignment="center" HorizontalAlignment="center"
FontWeight="Bold" Foreground="white" />
</Border>
<AdornedElementPlaceholder Name="customAdorner" VerticalAlignment="Center" >
<Border BorderBrush="red" BorderThickness="1" />
</AdornedElementPlaceholder>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

What is the type for content of button to store xaml data in resource?

In this post, I want to use a same solution to do with button. But I want to store the content to an other resource.(I mean XamlImage in below sample) What is the type for content of button to store xaml data in resource dictionary?
Below is sample from the post. I added XamlImage as path in resource but it doesn't work. So, what type should it be?
<Path x:Key="XamlImage" Data="M383.518,230.427C299.063,230.427 230.355,299.099 230.355,383.554 230.355,468.009 299.063,536.644 383.518,536.644 467.937,536.644 536.645,468.009 536.645,383.554 536.645,299.099 467.937,230.427 383.518,230.427z M340.229,0L426.771,0C436.838,0,445.035,8.19732,445.035,18.2643L445.035,115.303C475.165,122.17,503.532,133.928,529.634,150.43L598.306,81.6869C601.721,78.3074 606.359,76.3653 611.213,76.3653 616.031,76.3653 620.704,78.3074 624.12,81.6869L685.278,142.916C692.397,150.035,692.397,161.648,685.278,168.767L616.677,237.402C633.108,263.54,644.866,291.907,651.733,322.001L748.736,322.001C758.803,322.001,767,330.198,767,340.265L767,426.806C767,436.873,758.803,445.07,748.736,445.07L651.769,445.07C644.901,475.235,633.108,503.531,616.677,529.669L685.278,598.305C688.694,601.72 690.635,606.358 690.635,611.212 690.635,616.102 688.694,620.705 685.278,624.12L624.085,685.313C620.525,688.872 615.851,690.67 611.177,690.67 606.503,690.67 601.865,688.872 598.269,685.313L529.67,616.678C503.567,633.109,475.2,644.937,445.035,651.804L445.035,748.771C445.035,758.838,436.838,767,426.771,767L340.229,767C330.162,767,321.965,758.838,321.965,748.771L321.965,651.804C291.8,644.937,263.433,633.109,237.366,616.678L168.731,685.313C165.315,688.693 160.677,690.67 155.823,690.67 151.005,690.67 146.296,688.693 142.916,685.313L81.7221,624.12C74.6033,617.036,74.6033,605.424,81.7221,598.305L150.323,529.669C133.892,503.603,122.099,475.235,115.267,445.07L18.2643,445.07C8.19734,445.07,0,436.873,0,426.806L0,340.265C0,330.198,8.19734,322.001,18.2643,322.001L115.267,322.001C122.135,291.907,133.892,263.54,150.323,237.402L81.7221,168.767C78.3064,165.351 76.3655,160.713 76.3655,155.859 76.3655,150.97 78.3064,146.332 81.7221,142.916L142.916,81.7582C146.476,78.1988 151.149,76.4016 155.823,76.4016 160.497,76.4016 165.171,78.1988 168.731,81.7582L237.366,150.43C263.469,133.928,291.837,122.17,321.965,115.303L321.965,18.2643C321.965,8.19732,330.162,0,340.229,0z"/>
<Style x:Key="PathAppBarButtonStyle" BasedOn="{StaticResource AppBarButtonStyle}" TargetType="ButtonBase">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Path Width="20" Height="20"
Stretch="Uniform"
Fill="{Binding Path=Foreground, RelativeSource={RelativeSource Mode=TemplatedParent}}"
Data="{Binding Path=Content, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
</DataTemplate>
</Setter.Value>
</Setter>
<Style x:Key="CrossButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource PathAppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="CrossAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Cross"/>
<Setter Property="Content" Value="{StaticResource XamlImage}"/>
</Style>
You don't want to set an image resource as your content because Image is a control and it can only be in one place in your UI tree. You can reuse a DataTemplate though in your ContentTemplate. So just put an Image inside of that.

Windows Store Apps: Style TargetType="Page" not being applied

I have tried to create a Style to apply to any Page (like a Master Style) to include a little watermark in a corner, but this kind of style doesn't work.
<Style x:Key="WatermarkPageStyle" TargetType="Page">
<Setter Property="Template" >
<Setter.Value>
<ControlTemplate TargetType="Page">
<Grid>
<ContentPresenter/>
<TextBlock TextAlignment="Right" VerticalAlignment="Bottom" FontSize="25" Foreground="Blue" Text="Watermark"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
What's the problem? Is there a workaround?
Microsoft employee says that this is a known issue and you should set these values locally.

XAML style is applied to only the first rectangle. How to make it apply to all?

In a Windows 8 (WinRT) app, I am creating my own XAML style to get a dotted rectangle. In the setter for the style, I use Property="StrokeDashArray" Value="1,4". I then create a bunch of rectangles, and then explicitly set the style of those rectangles to this style I created. The first rectangle shows up with a dotted border - but the other two don't. However, if in addition to the Style={StaticResource myDottedStyle} I also specify the StrokeDashArray with each rectangle, then all them correctly show up with dotted borders.
Why is the dotted border only showing up for the first rectangle? How can I create a Style that is applied to all the rectangles without specifying the StrokeDashArray for each of them?
Here is a full code sample. In Windows 8 RTM, create a Blank XAML app project, and replace the Grid in the MainPage.xaml with the following:
<Page.Resources>
<Style x:Key="myDottedStyle" TargetType="Rectangle">
<Setter Property="Stroke"
Value="{StaticResource ApplicationForegroundThemeBrush}"/>
<Setter Property="StrokeThickness" Value="2"/>
<Setter Property="StrokeDashArray" Value="1,4"/>
</Style>
</Page.Resources>
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Rectangle Style="{StaticResource myDottedStyle}" Width="40"
HorizontalAlignment="Left"/>
<Rectangle Style="{StaticResource myDottedStyle}" Width="40"
HorizontalAlignment="Center"/>
<Rectangle Style="{StaticResource myDottedStyle}" Width="40"
HorizontalAlignment="Right"/>
</Grid>
Here is a screenshot of the output of this
I found a related question that talks about DataTemplates here but I can't figure out how to translate that into my problem.
You could optimize things a bit by not requiring it to re-draw the rectangle per each instance and substitute for a ContentControl instead since they appear the same but with minor differences. So something for example like;
<Style x:Key="MyDottedStyle" TargetType="ContentControl">
<!-- Add additional Setters Here -->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<Rectangle Stroke="{StaticResource ApplicationForegroundThemeBrush}"
StrokeThickness="2"
StrokeDashArray="1,4"
Width="40" Height="40"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
Margin="{TemplateBinding Margin}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- And now actually place it on your view -->
<ContentControl Style="{StaticResource MyDottedStyle}" HorizontalAlignment="Center"/>
This will allow you to not only clean things up because you can take your Style template and slap it over into say a Resource Dictionary to reduce clutter, but also makes it a little more efficient since you're not re-drawing your shape every time it's required. Hope this helps! Cheers!

Remove Stagger in Silverlight Chart X-Axis Labels

I created a Silverlight Column chart and rotated the X-Axis, following the guidelines of this MSDN Blog. The labels are rotated correctly, but I end up with staggered labels in my X-Axis, which does not fit well. I would like to remove the stagger from the labels.
Here is the XAML:
<toolkit:Chart Name="theColumnChart" BorderThickness="0" Margin="5"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Style="{StaticResource Chart}"
Template="{StaticResource ChartTemplate}" TitleStyle="{StaticResource ChartTitleStyle}">
<toolkit:Chart.Palette>
<visualizationToolkit:ResourceDictionaryCollection>
<ResourceDictionary>
<Style x:Key="DataPointStyle" TargetType="toolkit:ColumnDataPoint" BasedOn="{StaticResource ColumnDataPointStyle}">
<Setter Property="Background" Value="Goldenrod"/>
</Style>
</ResourceDictionary>
<ResourceDictionary>
<Style x:Key="DataPointStyle" TargetType="toolkit:ColumnDataPoint" BasedOn="{StaticResource ColumnDataPointStyle}">
<Setter Property="Background" Value="SaddleBrown"/>
</Style>
</ResourceDictionary>
</visualizationToolkit:ResourceDictionaryCollection>
</toolkit:Chart.Palette>
<toolkit:Chart.Axes>
<toolkit:LinearAxis Minimum="0" Orientation="Y" />
</toolkit:Chart.Axes>
<toolkit:Chart.Series>
<toolkit:ColumnSeries DependentValueBinding="{Binding ItemValue}" IndependentValueBinding="{Binding ItemKey}"
ItemsSource="{Binding Statistics1}" Title="{Binding SeriesTitle}">
<toolkit:ColumnSeries.IndependentAxis>
<toolkit:CategoryAxis Orientation="X">
<toolkit:CategoryAxis.AxisLabelStyle>
<Style TargetType="toolkit:AxisLabel">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="toolkit:AxisLabel">
<layout:LayoutTransformer>
<layout:LayoutTransformer.LayoutTransform>
<RotateTransform Angle="-45"/>
</layout:LayoutTransformer.LayoutTransform>
<TextBlock Text="{TemplateBinding FormattedContent}"/>
</layout:LayoutTransformer>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</toolkit:CategoryAxis.AxisLabelStyle>
</toolkit:CategoryAxis>
</toolkit:ColumnSeries.IndependentAxis>
</toolkit:ColumnSeries>
</toolkit:Chart.Series>
</toolkit:Chart>
Here is a picture of the problem:
When the labels are rotated by 90°, even with visually sufficient space between them, the stagger occurs, not sure why. So I end up with vertical staggered labels with plenty of space between them!
I came across the problem today, and I found a slightly hacky solution which does not require the modification of the control itself, but only involves a custom control template.
The following code shows the date labels vertically, and remove the stagger.
Every label is wrapped into a Canvas, which, as explained here, does not clip its content.
I had to modify the labels' margins to align them with axis marks.
<toolkit:DateTimeAxis.AxisLabelStyle>
<Style TargetType="toolkit:DateTimeAxisLabel">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="toolkit:DateTimeAxisLabel">
<Canvas Height="55">
<sdk:Label Content="{Binding StringFormat=\{0:dd/MM/yyyy\}}" Margin="-30,30,0,0" >
<sdk:Label.RenderTransform>
<RotateTransform Angle="-90" />
</sdk:Label.RenderTransform>
<sdk:Label.RenderTransformOrigin>
<Point>0.5, 0.5</Point>
</sdk:Label.RenderTransformOrigin>
</sdk:Label>
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</toolkit:DateTimeAxis.AxisLabelStyle>
here is the result:
Rachel Martin,
The labels above are still wide enough that there's not enough room to fit them all next to each other. You could choose to rotate the text more (which will narrow each label) or make the chart wider (which will provide more room for the labels). If you don't like either of those options, you can also remove the stagger behavior, but it's necessary to modify the Data Visualization code to do so; I explain how here: http://blogs.msdn.com/b/delay/archive/2010/03/06/turn-your-head-and-check-out-this-post-how-to-easily-rotate-the-axis-labels-of-a-silverlight-wpf-toolkit-chart.aspx#10083036
Hope this helps!