Bind a property of the WPF Image - wpf

I have the following WPF UserControl
I want that the blue border be displayed only when the object has its (dependency bool property) property IsSelected to true.
Is that possible?
<Canvas>
<Image x:Name="Dot">
<Image.Source>
<DrawingImage>
<DrawingImage.Drawing>
<DrawingGroup>
<GeometryDrawing>
<GeometryDrawing.Pen>
<Pen Brush="Blue" Thickness="2" x:Name="BigCircleThickness"/>
</GeometryDrawing.Pen>
<GeometryDrawing.Geometry>
<GeometryGroup>
<EllipseGeometry x:Name="BigCircle" Center="0,0" RadiusX="7" RadiusY="7"/>
</GeometryGroup>
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing>
<GeometryDrawing.Brush>
<SolidColorBrush Color="Blue" />
</GeometryDrawing.Brush>
<GeometryDrawing.Geometry>
<GeometryGroup>
<EllipseGeometry x:Name="SmallCircle" Center="0,0" RadiusX="2" RadiusY="2"/>
</GeometryGroup>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
</Image.Source>
</Image>
</Canvas>
In other words, I need that when IsSeleted = false "BigCircle" dissapear.
Is that possible?

You could use a DataTrigger. Something like this:
<Image>
<Image.Style>
<Setter Property="Source" Value={StaticResource MyDrawingImage_NoBorder}" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected}" Value="True">
<Setter Property="Source" Value={StaticResource MyDrawingImage_WithBorder}" />
</DataTrigger>
</Style.Triggers>
</Image.Style>
</Image>

Related

How to scale an svg image inserted using DrawingBrush

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>

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>

How to combine two different styles into one in xaml?

In my xaml page, I have one style and one drawingbrush which are given below -
<Style x:Key="ICON_STYLE" TargetType="Rectangle">
<Setter Property="Fill">
<Setter.Value>
<DrawingBrush Viewbox="0,0,39.125,39.125" ViewboxUnits="Absolute">
<DrawingBrush.Drawing>
<GeometryDrawing Brush="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=uiEntityViews:BaseView}, Path=MeSiteColor}" Geometry="F1M19.5625,0.999954C29.8144,0.999954 38.125,9.31053 38.125,19.5625 38.125,29.8142 29.8143,38.1249 19.5625,38.1249 9.31073,38.1249 1,29.8142 1,19.5625 1,9.31053 9.31064,0.999954 19.5625,0.999954z">
<GeometryDrawing.Pen>
<Pen DashCap="Square" EndLineCap="Flat" LineJoin="Round" MiterLimit="10" StartLineCap="Flat" Thickness="2">
<Pen.Brush>
<LinearGradientBrush EndPoint="0.849422,0.849423" StartPoint="0.150577,0.150578">
<GradientStop Color="#FF657783" Offset="0"/>
<GradientStop Color="White" Offset="0.146"/>
<GradientStop Color="#FF2C4758" Offset="1"/>
</LinearGradientBrush>
</Pen.Brush>
<Pen.DashStyle>
<DashStyle/>
</Pen.DashStyle>
</Pen>
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
</Setter.Value>
</Setter>
</Style>
<DrawingBrush x:Key="ICON_BRUSH">
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="Gray" Geometry="F1 M0,25 L25,50, 50,25 25,0z">
<GeometryDrawing.Pen>
<Pen DashCap="Triangle" EndLineCap="Flat" LineJoin="Bevel" MiterLimit="10" StartLineCap="Flat" Thickness="5">
<Pen.Brush>
<LinearGradientBrush>
<GradientStop Color="Red" Offset="0"/>
<GradientStop Color="Green" Offset="1"/>
</LinearGradientBrush>
</Pen.Brush>
<Pen.DashStyle>
<DashStyle/>
</Pen.DashStyle>
</Pen>
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingGroup>
</DrawingBrush.Drawing>
How do I combine these two into one style. I have tried the following but it did not work.
<Style x:Key="COMBINED_NODE_ICON" TargetType="Rectangle" BasedOn="{StaticResource ICON_STYLE}">
<Setter Property="Fill">
<Setter.Value>
<DrawingBrush TileMode="None">
<DrawingBrush.Drawing>
<DrawingGroup>
<DrawingGroup.Transform>
<TranslateTransform X="0.2" Y="0.2" />
</DrawingGroup.Transform>
<GeometryDrawing Brush="{StaticResource ICON_BRUSH}">
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0,0,1,1" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</Setter.Value>
</Setter>
Any help will be highly appreciated. Thanks.
This should work (dkozl plus BasedOn):
<Style x:Key="COMBINED_NODE_ICON"
TargetType="Rectangle"
BasedOn="{StaticResource ICON_STYLE}">
<Setter Property="Fill"
Value="{StaticResource ICON_BRUSH}" />
</Style>
The BasedOn part can be omitted (pure dkozl) as long as your base style (ICON_STYLE) contains nothing but the Fill Setter, since the Fill property is overridden inside style COMBINED_NODE_ICON.
But also your code is working, if you add the last line of
<DrawingBrush x:Key="ICON_BRUSH">
...
</DrawingBrush>
and the last line of
<Style x:Key="COMBINED_NODE_ICON" TargetType="Rectangle" BasedOn="{StaticResource ICON_STYLE}">
...
</Style>

Is there opportunity to combine rectangles to one rectangle?

I have some rectangles which their heights are same. But i filled them with different color. Can i combine them as result i get Rectangle? I can do it with RectangleGeometry but i need Rectangle type
How do you want to combine the colours?
Do you just want to specify 2 rectangular regions which overlap but use different colors with a level of transparency so that the colours blend together?
Or do you want the Rectangle subdivided and using different colours in different regions?
Is there a reason you need to keep it as a Rectangle?
Here's a way to keep it as a Rectangle but specify your 2 colours to combine/mix as the Fill:
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<Rectangle Width="100" Height="100">
<Rectangle.Fill>
<DrawingBrush Viewport="0,0,1,1" TileMode="Tile">
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing>
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0,0,1,1" />
</GeometryDrawing.Geometry>
<GeometryDrawing.Brush>
<SolidColorBrush Color="Red" Opacity="1"/>
</GeometryDrawing.Brush>
</GeometryDrawing>
<GeometryDrawing>
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0,0,1,1" />
</GeometryDrawing.Geometry>
<GeometryDrawing.Brush>
<SolidColorBrush Color="White" Opacity=".5"/>
</GeometryDrawing.Brush>
</GeometryDrawing>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</Rectangle.Fill>
</Rectangle>
</Grid>
</Page>
Or this one for subdivided rectangles:
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<Rectangle Width="100" Height="100">
<Rectangle.Fill>
<DrawingBrush Viewport="0,0,1,1" TileMode="None">
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing>
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0,0,1,1" />
</GeometryDrawing.Geometry>
<GeometryDrawing.Brush>
<SolidColorBrush Color="Yellow"/>
</GeometryDrawing.Brush>
</GeometryDrawing>
<GeometryDrawing>
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0,0,0.5,0.5" />
</GeometryDrawing.Geometry>
<GeometryDrawing.Brush>
<SolidColorBrush Color="Red"/>
</GeometryDrawing.Brush>
</GeometryDrawing>
<GeometryDrawing>
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0.5,0.5,0.5,0.5" />
</GeometryDrawing.Geometry>
<GeometryDrawing.Brush>
<SolidColorBrush Color="Green"/>
</GeometryDrawing.Brush>
</GeometryDrawing>
<GeometryDrawing>
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0.25,0.25,0.25,0.25" />
</GeometryDrawing.Geometry>
<GeometryDrawing.Brush>
<SolidColorBrush Color="Blue"/>
</GeometryDrawing.Brush>
</GeometryDrawing>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</Rectangle.Fill>
</Rectangle>
</Grid>
</Page>
(move the brush described by the DrawingBrush into Resources if you intend to use it in multiple places....and/or create a new Style for Rectangles).
Rectangle is sealed so it can be overridden, and it's not a Control so you can't change a template.
You might want to consider doing your own "Shape", so that you can better encapsulate the enhanced behaviour of "your" Rectangle.
Here's an example to get your started.
http://www.codeproject.com/Articles/21449/WPF-PartiallyRoundedRectangle-Choose-Which-Corners

Help with WPF Binding

I need to bind the custom dependency property to the Image elements inside a control.
Now the Label's Foreground binds very well to TextForeground, but not the GeometryDrawing inside the Image (the Image remains Transparent).
What is wrong?
<UserControl x:Class="MyStopControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d" Height="12" Width="24">
<Canvas >
<Image x:Name="Dot" Canvas.Left="0" Canvas.Top="0">
<Image.Source>
<DrawingImage>
<DrawingImage.Drawing>
<DrawingGroup>
<GeometryDrawing>
<GeometryDrawing.Pen>
<Pen Brush="{Binding RelativeSource={x:Static RelativeSource.Self},Path=TextForeground}" Thickness="2" x:Name="BigCircleThickness"/>
</GeometryDrawing.Pen>
<GeometryDrawing.Geometry>
<GeometryGroup>
<EllipseGeometry x:Name="BigCircle" Center="0,0" RadiusX="7" RadiusY="7"/>
</GeometryGroup>
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing>
<GeometryDrawing.Pen>
<Pen Brush="{Binding RelativeSource={x:Static RelativeSource.Self},Path=TextForeground}" Thickness="1"/>
</GeometryDrawing.Pen>
<GeometryDrawing.Geometry>
<GeometryGroup>
<EllipseGeometry x:Name="MediumCircle" Center="0,0" RadiusX="4" RadiusY="4"/>
</GeometryGroup>
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="{Binding RelativeSource={x:Static RelativeSource.Self},Path=TextForeground}">
<GeometryDrawing.Geometry>
<GeometryGroup>
<EllipseGeometry x:Name="SmallCircle" Center="0,0" RadiusX="2" RadiusY="2"/>
</GeometryGroup>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
</Image.Source>
</Image>
<Border x:Name="StopShadow"
Background="{Binding ElementName=TextBackground}"
LayoutTransform="{Binding ElementName=StopText, Path=LayoutTransform}">
<Label x:Name="StopLabel"
Content="Bla bla some text"
Foreground="{Binding ElementName=TextForeground}" />
</Border>
</Canvas>
</UserControl>
GeometryDrawing does not have a TextForeground property. You are referencing Self, which would be the GeometryDrawing. Change your RelativeSource if you are trying to grab the TextForeground from a different Control.
<GeometryDrawing.Pen>
<Pen Brush="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=TextForeground}" Thickness="1"/>
</GeometryDrawing.Pen>
<UserControl x:Name="MyStopControl" >
...
<Pen Brush="{Binding ElementName=MyStopControl, Path=TextForeground}"/>
...
</UserControl>

Resources