<DockPanel LastChildFill="True" Height="18">
<Image Height="18" Width="80">
<Image.Source>
<DrawingImage>
<DrawingImage.Drawing>
<GeometryDrawing Brush="Black">
<GeometryDrawing.Geometry>
<LineGeometry StartPoint="0,9" EndPoint="38,9" />
</GeometryDrawing.Geometry>
<GeometryDrawing.Pen>
<Pen DashCap="Flat"
Brush="Black"
Thickness="0.5"
DashStyle="{x:Static DashStyles.Dot}, Mode=OneTime}"
/>
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingImage.Drawing>
</DrawingImage>
</Image.Source>
</Image>
<TextBlock Height="18" Text="{Binding Name, Mode=OneTime}" Margin="3,2,5,0" />
</DockPanel>
Remove DashCap="Flat" and you will see the dots. There are other DashCaps that will work: Round, Square, Triangle.
Related
Here is a test app that just shows a hatched ellipse in a window. No matter how I write it, the background of the ellipse is transparent; not the color I'm setting the GeometryDrawing. I'm stumped. The resulting picture shows the background of the ellipse as transparent when it should be Green.
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApp2"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Background="Red"
mc:Ignorable="d">
<Window.Resources>
<ResourceDictionary>
<DrawingBrush x:Key="HatchBrush"
Stretch="UniformToFill"
TileMode="Tile"
Viewbox="0 0 10 10"
ViewboxUnits="Absolute"
Viewport="0 0 10 10"
ViewportUnits="Absolute">
<DrawingBrush.Drawing>
<GeometryDrawing Brush="Green">
<GeometryDrawing.Geometry>
<GeometryGroup>
<LineGeometry StartPoint="0 0"
EndPoint="10 0" />
<LineGeometry StartPoint="0 0"
EndPoint="0 10" />
</GeometryGroup>
</GeometryDrawing.Geometry>
<GeometryDrawing.Pen>
<Pen Brush="Yellow"
EndLineCap="Square"
StartLineCap="Square"
Thickness="3" />
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
</ResourceDictionary>
</Window.Resources>
<Grid Margin="5"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Ellipse x:Name="c_Ellipse"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Fill="{StaticResource HatchBrush}"
Stroke="Black" />
</Grid>
</Window>
This is what I get:
The background of the ellipse should be Green:
<GeometryDrawing Brush="Green">
There is no filled geometry that uses the GeometryDrawing's Brush.
You may use a RectangleGeometry instead of two LineGeometries:
<GeometryDrawing Brush="Green">
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0,0,10,10"/>
</GeometryDrawing.Geometry>
<GeometryDrawing.Pen>
<Pen Brush="Yellow" Thickness="1.5"/>
</GeometryDrawing.Pen>
</GeometryDrawing>
The arrow is supposed to have a red fill but the fill is missing at certain angles of the RotateTransform. It vanishes from ~92° to ~279°
In my full project it also occured that only a part of the arrow was filled. Is this a WPF rendering bug or am I doing something wrong here?
<StackPanel Orientation="Vertical">
<Slider x:Name="slider"
Value="180"
Minimum="0"
Maximum="360" />
<Canvas Width="296"
Height="296">
<Canvas.Background>
<DrawingBrush Stretch="Uniform">
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="Red">
<GeometryDrawing.Pen>
<Pen Brush="Lime"
Thickness="2" />
</GeometryDrawing.Pen>
<GeometryDrawing.Geometry>
<PathGeometry>
<PathGeometry.Transform>
<TransformGroup>
<RotateTransform Angle="{Binding ElementName=slider, Path=Value}" />
</TransformGroup>
</PathGeometry.Transform>
<PathGeometry.Figures>
<PathFigure IsClosed="True"
StartPoint="100 50">
<LineSegment Point="50 87.5" />
<LineSegment Point="50 62.5" />
<LineSegment Point=" 0 62.5" />
<LineSegment Point=" 0 37.5" />
<LineSegment Point="50 37.5" />
<LineSegment Point="50 12.5" />
</PathFigure>
</PathGeometry.Figures>
</PathGeometry>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</Canvas.Background>
</Canvas>
</StackPanel>
You could simply rotate a Path by its RenderTransform:
<Path Width="296" Height="296" Stretch="Uniform"
Fill="Red" Stroke="Lime" StrokeThickness="8"
Data="M100,50 L50,87.5 50,62.5 0,62.5 0,37.5 50,37.5 50,12.5Z"
RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform>
<RotateTransform Angle="{Binding ElementName=slider, Path=Value}" />
</Path.RenderTransform>
</Path>
I would like to draw circular geometry in VisualBrush (in order to create an OpacityMask), the result however are of rather low quality:
This image is 500% zoomed in but the cut off of the circle is apparent (especially on top and bottom) and even at original size the mask is rather blurry. The image was generated with following code:
<Border Background="Blue">
<Border.OpacityMask>
<VisualBrush TileMode="None" Stretch="Uniform" AlignmentX="Center" AlignmentY="Center">
<VisualBrush.Visual>
<Image>
<Image.Source>
<DrawingImage>
<DrawingImage.Drawing>
<GeometryDrawing Brush="Black">
<GeometryDrawing.Geometry>
<EllipseGeometry Center="0,0" RadiusX="1" RadiusY="1" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingImage.Drawing>
</DrawingImage>
</Image.Source>
</Image>
</VisualBrush.Visual>
</VisualBrush>
</Border.OpacityMask>
</Border>
How can I fix the mask so that is neither blurry nor cut off?
This may be better. At least it is simpler.
<Border Background="Blue">
<Border.OpacityMask>
<DrawingBrush Stretch="Uniform" AlignmentX="Center" AlignmentY="Center">
<DrawingBrush.Drawing>
<GeometryDrawing Brush="Black">
<GeometryDrawing.Geometry>
<EllipseGeometry RadiusX="1" RadiusY="1" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
</Border.OpacityMask>
</Border>
I've created a VisualBrush in WPF to give me a wavy underline for a character.
<VisualBrush x:Key="WavyBrush">
<VisualBrush.Visual>
<Path Data="M 0,2 L 2,0 4,2 6,0 8,2 10,0 12,2" Stroke="Black" />
</VisualBrush.Visual>
</VisualBrush>
It works great except when I put the result in a DataGrid and select the row. If an unselected row has black text with white background and selecting the row turns the text white, (and the background blue or some other color) my VisualBrush with Stroke="Black" stays black, doesn't go white and looks confusing.
Is there a way to get the brush to act like color of text?
You can use DataTrigger to change the color of the brush when the row is selected. The code uses ListBox but you could easily adapt it to use DataGrid.
<Window.Resources>
<VisualBrush x:Key="WavyBrush">
<VisualBrush.Visual>
<Path Data="M 0,2 L 2,0 4,2 6,0 8,2 10,0 12,2" Stroke="Black" />
</VisualBrush.Visual>
</VisualBrush>
<VisualBrush x:Key="whiteWavyBrush">
<VisualBrush.Visual>
<Path Data="M 0,2 L 2,0 4,2 6,0 8,2 10,0 12,2" Stroke="White" />
</VisualBrush.Visual>
</VisualBrush>
</Window.Resources>
<Grid>
<ListBox ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Height="50" Width="350">
<Border x:Name="border" Width="350" Height="10" VerticalAlignment="Bottom" Background="{StaticResource WavyBrush}">
</Border>
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBoxItem}},Path=IsSelected}" Value="True">
<Setter TargetName="border" Property="Background" Value="{StaticResource whiteWavyBrush}" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
If anyone else is interested, the DrawingBrush acts like text and changes color when selected.
<DrawingBrush x:Key="TextBoxWavyBrush">
<DrawingBrush.Drawing>
<DrawingGroup>
<DrawingGroup.Children>
<GeometryDrawing Geometry="M 0,2 L 2,0 4,2 6,0 8,2 10,0 12,2">
<GeometryDrawing.Pen>
<Pen Thickness="1" StartLineCap="Round" EndLineCap="Round" LineJoin="Round" Brush="{Binding RelativeSource={RelativeSource AncestorType=TextBox, Mode=FindAncestor}, Path=Foreground}"/>
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingGroup.Children>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
Is there a way in WPF when two shape objects overlap each other that the overlapping portions of the object get painted in a different brush?
Worked it out.
You can use a geometry drawing containing a GeometryGroup with a fill rule of EvenOdd. This paints any overlapping items in white. Then just put another image over the top with CombinedGeometry containing the same objects as the Geometry group with a GeometryCombineMode of Intersect and that will highlight the intersect in your custom brush. The sample code is below:
<Grid>
<Image Stretch="None">
<Image.Source>
<DrawingImage>
<DrawingImage.Drawing>
<GeometryDrawing Brush="Red">
<GeometryDrawing.Pen>
<Pen Brush="Black" Thickness="3" />
</GeometryDrawing.Pen>
<GeometryDrawing.Geometry>
<GeometryGroup FillRule="EvenOdd">
<EllipseGeometry RadiusX="80" RadiusY="80" Center="0,0" />
<EllipseGeometry RadiusX="80" RadiusY="80" Center="40,0" />
</GeometryGroup>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingImage.Drawing>
</DrawingImage>
</Image.Source>
</Image>
<Image HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stretch="None">
<Image.Source>
<DrawingImage>
<DrawingImage.Drawing>
<GeometryDrawing Brush="LightBlue">
<GeometryDrawing.Geometry>
<CombinedGeometry GeometryCombineMode="Intersect">
<CombinedGeometry.Geometry1>
<EllipseGeometry RadiusX="80" RadiusY="80" Center="0,0" />
</CombinedGeometry.Geometry1>
<CombinedGeometry.Geometry2>
<EllipseGeometry RadiusX="80" RadiusY="80" Center="40,0" />
</CombinedGeometry.Geometry2>
</CombinedGeometry>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingImage.Drawing>
</DrawingImage>
</Image.Source>
</Image>
</Grid>
Thanks!