How to scale an svg image inserted using DrawingBrush - wpf

Is there a way to scale an svg image inserted using DrawingBrush as in the following code?
<Style x:Key="HamburgerMenuItemStyle" TargetType="{x:Type MenuItem}">
<Setter Property="Template" Value="{StaticResource MenuItemControlTemplate1}"/>
<Setter Property="Icon">
<Setter.Value>
<DrawingImage>
<DrawingImage.Drawing>
<GeometryDrawing Geometry="M6 36v-3h36v3Zm0-10.5v-3h36v3ZM6 15v-3h36v3Z"
Brush="Red"/>
</DrawingImage.Drawing>
</DrawingImage>
</Setter.Value>
</Setter>
</Style>

According to your description, I think you should code as below:
<Style x:Key="HamburgerMenuItemStyle" TargetType="{x:Type MenuItem}">
<Setter Property="Template" Value="{StaticResource MenuItemControlTemplate1}"/>
<Setter Property="Icon">
<Setter.Value>
<Image Stretch="UniformToFill" Width="auto" Height="auto" HorizontalAlignment="Left">
<Image.Source>
<DrawingImage>
<DrawingImage.Drawing>
<GeometryDrawing Geometry="M6 36v-3h36v3Zm0-10.5v-3h36v3ZM6 15v-3h36v3Z" Brush="Red"/>
</DrawingImage.Drawing>
</DrawingImage>
</Image.Source>
</Image>
</Setter.Value>
</Setter>
</Style>
Note:
Since I didn't have the Template property, I removed it. If you have problems displaying the icon despite this property, you should check it.
Also, if you are not sensitive to the use of Drawing Image, you can use the Path tag
<Path Stretch="Fill" Height="30" Width="30" Data="M6 36v-3h36v3Zm0-10.5v-3h36v3ZM6 15v-3h36v3Z" Fill="Red"></Path>

Related

Access user control property in App.xaml style WPF

I'm trying to set the "Stroke" property of Path in my visual brush (Defined in App.xaml) via the property from my model. I'm using this style in my another control template in a usercontrol.
Style in User control resources:
<Ellipse x:Name="slideThumb" Height="25" Width="25" Stroke="{Binding ThumbColor, UpdateSourceTrigger=PropertyChanged}">
<Ellipse.Style>
<Style TargetType="{x:Type Ellipse}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsHatchBrush}" Value="true">
<Setter Property="Fill" Value="{StaticResource HatchBrushVertical}" />
</DataTrigger>
<DataTrigger Binding="{Binding IsHatchBrush}" Value="false">
<Setter Property="Fill" Value="{Binding ThumbColor, UpdateSourceTrigger=PropertyChanged}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
</Ellipse>
Brush Defined in App.xaml:
<VisualBrush x:Key="HatchBrushVertical" TileMode="Tile" Viewport="0,0,2,3" ViewportUnits="Absolute" Viewbox="0,0,5,5" ViewboxUnits="Absolute">
<VisualBrush.Transform>
<RotateTransform Angle="45" />
</VisualBrush.Transform>
<VisualBrush.Visual>
<Canvas>
<Path Data="M 0 0 L 0 10" Stroke="{Binding Path=Stroke, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Ellipse}}}" StrokeThickness="5"/>
</Canvas>
</VisualBrush.Visual>
</VisualBrush>
Problem here is, I'm not able to set the Stroke property of the visal brush in app.xaml through the binding.
Need help. Thanks in advance
You may perhaps use the Brush as an OpacityMask.
First, create a (simpler) DrawingBrush instead of a VisualBrush:
<DrawingBrush x:Key="HatchBrush" TileMode="Tile"
Viewport="0,0,3,3" ViewportUnits="Absolute"
Viewbox="0,0,2,2" ViewboxUnits="Absolute">
<DrawingBrush.Drawing>
<GeometryDrawing Geometry="M-1,2 L2,-1 M0,3 L3,0">
<GeometryDrawing.Pen>
<Pen Thickness="0.7" Brush="Black"/>
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
Then write a DataTrigger like this:
<DataTrigger Binding="{Binding IsHatchBrush}" Value="True">
<Setter Property="OpacityMask" Value="{StaticResource HatchBrush}" />
</DataTrigger>

Have DrawingImage inherit color from containing Button

I have a few buttons that have a common style. This style has a ContentPresenter, which is filled with a DrawingImage in the button declaration.
This works just fine when the DrawingImage uses a predefined brush. However I would very much like my DrawingImage to use the Foreground color that is used in the style, or on the button if it is overridden there.
How can I accomplish this?
My current style:
<UserControl.Resources>
<DrawingImage x:Key="SomeIcon">
<DrawingImage.Drawing>
<DrawingGroup>
<DrawingGroup>
<GeometryDrawing Brush="White" Geometry="PATH" />
<GeometryDrawing Brush="White" Geometry="OTHER_PATH" />
</DrawingGroup>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
<Style x:Key="MyButton" TargetType="{x:Type Button}">
<Setter Property="Foreground" Value="Blue" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<ContentPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid>
<Button Style="{StaticResource MyButton">
<!-- I want this icon to be Blue as inherited from the style. -->
<Image Source="{StaticResource SomeIcon}"/>
</Button>
<Button Style="{StaticResource MyButton" Foreground="Red">
<!-- I want this icon be Red as overriden by the button -->
<Image Source="{StaticResource SomeIcon}"/>
</Button>
</Grid>
I only want pure XAML answers. Other XAML routes towards the same goal are also appreciated, for instance using Path instead of DrawingImage.
You could declare the icon resource as a Geometry, and have a Button Style with a Path like this:
<Window.Resources>
<Geometry x:Key="SomeIcon">M0,20 L20,0 40,20 20,40Z</Geometry>
<Style x:Key="PathButtonStyle" TargetType="Button">
<Setter Property="Foreground" Value="Blue"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<ControlTemplate TargetType="Button">
<Path Fill="{TemplateBinding Background}"
Stroke="{TemplateBinding Foreground}"
Data="{TemplateBinding Content}"
Stretch="None"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Button Style="{StaticResource PathButtonStyle}"
Content="{StaticResource SomeIcon}"/>
</Grid>

Volume Slider CustomControl

I searched the last hours for a custom control that looks like this:
Triangular volume control
It's like a simple slider, but this growing size to the right side is my problem.
I don't know how to do this.
Have anyone an idea?
You can define a geometry that has the shape of a triangle and use that as a OpacityMask of the Track. The Track has a repeat button on the left to decrease the value and on the right to increase it. You just need to bind the background of the left button to the background of your slider along with the background of the thumb. You also should make the templates of both the thumb and the repeaters very simple to only show the background color.
Here is an example style:
<Style TargetType="{x:Type Slider}">
<Setter Property="Background" Value="Gray"/>
<Setter Property="Height" Value="20"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Slider}">
<ControlTemplate.Resources>
<Style TargetType="{x:Type RepeatButton}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="IsTabStop" Value="false"/>
<Setter Property="Focusable" Value="false"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}">
<Border Background="{TemplateBinding Background}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<PathGeometry x:Key="Triangle">
<PathFigure StartPoint="0,1">
<LineSegment Point="1,1"/>
<LineSegment Point="1,0"/>
<LineSegment Point="0,1"/>
</PathFigure>
</PathGeometry>
</ControlTemplate.Resources>
<Grid>
<Grid>
<Grid.OpacityMask>
<DrawingBrush>
<DrawingBrush.Drawing>
<GeometryDrawing Brush="Black" Geometry="{StaticResource Triangle}"/>
</DrawingBrush.Drawing>
</DrawingBrush>
</Grid.OpacityMask>
<Track Name="PART_Track" Value="{TemplateBinding Value}">
<Track.Thumb>
<Thumb Width="10" Background="{TemplateBinding Background}">
<Thumb.Template>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border Background="{TemplateBinding Background}"/>
</ControlTemplate>
</Thumb.Template>
</Thumb>
</Track.Thumb>
<Track.DecreaseRepeatButton>
<RepeatButton Background="{TemplateBinding Background}" Command="Slider.DecreaseLarge"/>
</Track.DecreaseRepeatButton>
<Track.IncreaseRepeatButton>
<RepeatButton Background="Transparent" Command="Slider.IncreaseLarge"/>
</Track.IncreaseRepeatButton>
</Track>
</Grid>
<Path
Data="{StaticResource Triangle}"
Stretch="Fill"
Stroke="Black"
StrokeThickness="1"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
(This is just an example which disregards a lot of things like e.g. the Orientation)

Use image as WPF Button icon mask?

I'd like to know if it's possible to do the following:
create a black and white image, say of a dog
add the image to a button as a mask
change the style using (data) triggers, e.g. disabled - the dog is grey, "loading" - the dog is red, "ready" the dog is yellow, etc.
Basically I want to create button icons using pixels but be able to set the color at runtime depending on triggers. Something like this:
After 2 hours of googling here's the answer
<Window x:Class="IconTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<!-- button style -->
<Style x:Key="ToolButton" TargetType="Button">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Width="16" Height="16" Background="#ffbbbbbb">
<Rectangle Name="rect" Fill="Black" OpacityMask="{TemplateBinding Content}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="rect" Property="Fill" Value="Green" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="rect" Property="Fill" Value="Yellow" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Button Width="16" Height="16" Style="{StaticResource ToolButton}">
<ImageBrush ImageSource="/test.png"/>
</Button>
</Grid>
</Window>
You can define an OpacityMask for the Button. I believe you will be able to add triggers (if you need them) to change the Background of Button.
Sample:
<Button Height="100" Width="100" Background="Green">
<Button.OpacityMask>
<DrawingBrush AlignmentX="Left" AlignmentY="Top">
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="#33000000">
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0,0,40,40" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FF000000">
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="10,10,20,20">
<RectangleGeometry.Transform>
<RotateTransform Angle="45" CenterX="20" CenterY="20" />
</RectangleGeometry.Transform>
</RectangleGeometry>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</Button.OpacityMask>
</Button>
In my opinion, you don't need create image mask in WPF to achieve your requirement. You could simply edit the control template of the button class.
Please refer to the Ellipse button example in this page. Control Template
Then you could simply change the Fill Color of that shape using trigger. Trigger
Cheers,

Looking for a Office 2007 Style zoom slider template

Has anyone seen a good template for a Office 2007 style zoom slider?
As shown in this picture
alt text http://www.theexceladdict.com/images/zoom_controls_excel_2007_2003.jpg
Something like this would be very easy to create.
First create a button style:
<Style x:Key="ZoomIncreaseDecreaseStyle" TargetType="{x:Type RepeatButton}">
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="IsTabStop" Value="false" />
<Setter Property="Focusable" Value="false" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}">
<Grid>
<Ellipse Stroke="Gray" x:Name="Ellipse">
<Ellipse.Fill>
<RadialGradientBrush ... />
</Ellipse.Fill>
</Ellipse>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
<ControlTemplate.Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="Ellipse" Property="Fill">
<RadialGradientBrush ... />
</Setter>
</Trigger>
</ControlTemplate.Trigger>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style>
Then modify the ControlTemplate in Blend (create copy), and add something like this around the <Grid>:
<DockPanel>
<RepeatButton
DockPanel.Dock="Left"
Command="{x:Stastic Slider.DecreaseLarge}"
ControlTemplate="{StaticResource ZoomIncreaseDecreaseStyle}">
<Path Data="{StaticResource MinusGeometry}" />
</RepeatButton>
<RepeatButton
DockPanel.Dock="Right"
Command="{x:Stastic Slider.IncreaseLarge}"
ControlTemplate="{StaticResource ZoomIncreaseDecreaseStyle}">
<Path Data="{StaticResource PlusGeometry}" />
</RepeatButton>
<Grid>
...
You can play with the button stroke color, gradient fill, and the + and - paths to get it the way you want it. I assume the actual Office 2007 buttons are copyrighted so you probably won't be able to copy them too closely without infringing. But this will give you something visually very similar.

Resources