How do I create repeating diagonal lines as a background in WPF? - wpf

OK, I've wracked my brain, Google, and stackoverflow trying to figure this out, but just can't quite get it. I'm trying to use a DrawingBrush with a DrawingGroup to do two things to the background of my WPF application (latest version). One, I want to have a RadialGradientBrush to put a subtle gradient in my background. This part is working just fine. The second part that I'm trying to accomplish is that I want to also have repeating diagonal lines as part of that background. I know I could do it with an image, but would rather use geometries, as I'm trying to learn and master WPF. Here's what I have so far. The radial appears fine, but the lines do not. Any help would be appreciated.
<Style x:Key="WindowBackground" TargetType="Grid">
<Setter Property="Background">
<Setter.Value>
<DrawingBrush>
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing>
<GeometryDrawing.Brush>
<RadialGradientBrush GradientOrigin="0.5,0.5" RadiusX="0.5" RadiusY="0.5">
<GradientStop Color="#EE9D40" Offset="0"/>
<GradientStop Color="#BF8230" Offset="1"/>
</RadialGradientBrush>
</GeometryDrawing.Brush>
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0,0,1,1"/>
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing>
<GeometryDrawing.Brush>
<DrawingBrush TileMode="Tile" Stretch="None" Viewbox="0,0,1,1" Viewport="0,0,25,25" ViewportUnits="Absolute">
<DrawingBrush.RelativeTransform>
<TranslateTransform X="0" Y="0" />
</DrawingBrush.RelativeTransform>
<DrawingBrush.Drawing>
<GeometryDrawing Brush="#20FFFFFF" Geometry="M10,0 22,0 12,25 0,22 Z" />
</DrawingBrush.Drawing>
</DrawingBrush>
</GeometryDrawing.Brush>
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0,0,1,1"/>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</Setter.Value>
</Setter>
</Style>

This trick should work.
<LinearGradientBrush EndPoint="0,0" StartPoint="8,8"
MappingMode="Absolute" SpreadMethod="Repeat">
<GradientStop Color="Black" Offset="0" />
<GradientStop Color="Black" Offset="0.1" />
<GradientStop Color="White" Offset="0.1" />
<GradientStop Color="White" Offset="1" />
</LinearGradientBrush>

Try rotating a horizontal line brush to avoid the corner gaps:
<VisualBrush TileMode="Tile"
Viewport="0,0,5,5" ViewportUnits="Absolute"
Viewbox="0,0,5,5" ViewboxUnits="Absolute">
<VisualBrush.Visual>
<Grid Background="White" Height="5">
<Path Stroke="Black" Data="M 0 3 l 8 0" />
</Grid>
</VisualBrush.Visual>
<VisualBrush.RelativeTransform>
<RotateTransform CenterX="0.5" CenterY="0.5" Angle="45" />
</VisualBrush.RelativeTransform>
</VisualBrush>

I finally got it working, but not with a single composite brush like I was wanting. I used the following styles:
<Style x:Key="WindowBackground" TargetType="Grid">
<Setter Property="Background">
<Setter.Value>
<RadialGradientBrush GradientOrigin="0.5,0.5" RadiusX="0.5" RadiusY="0.5">
<GradientStop Color="#EAA659" Offset="0"/>
<GradientStop Color="#BF8230" Offset="1"/>
</RadialGradientBrush>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="HatchOverlay" TargetType="Rectangle">
<Setter Property="Fill">
<Setter.Value>
<VisualBrush Opacity=".1" TileMode="Tile" Viewport="0,0,10,20" ViewportUnits="Absolute">
<VisualBrush.Visual>
<Canvas>
<Path Stroke="#825821" Data="M 0 0 l 10 20" />
</Canvas>
</VisualBrush.Visual>
</VisualBrush>
</Setter.Value>
</Setter>
</Style>
Then, to enable it at run time, I added a rectangle as the first child of my grid, like so:
<Grid Style="{StaticResource WindowBackground}">
<Rectangle Style="{StaticResource HatchOverlay}"/>...
This gave me the effect that I was after. Thanks for your help; I'll up-vote each of you.

Related

using a DrawingBrush resource for a Grid Background

I am trying to set the background of a UniformGrid to a DrawingBrush resource and I am getting an error. How do I do this:
<UniformGrid Rows="1" Columns="1" Height="75" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Grid.Row="2">
<UniformGrid.Background>
<DrawingBrush="{StaticResource SteelBrush_Vert}"/>
</UniformGrid.Background>
Error: White Space is missing
This is the Steel_Brsh_Vert I am trying to use:
<DrawingBrush x:Key="SteelBrush_Vert" Stretch="Fill">
<DrawingBrush.Drawing >
<DrawingGroup>
<GeometryDrawing Geometry="M114.000,293.847C114.000,280.324,114.045,269.362,114.100,269.362L391.900,269.362C391.955,269.362,392.000,280.324,392.000,293.847L392.000,485.878C392.000,499.400,391.955,510.362,391.900,510.362L114.100,510.362C114.045,510.362,114.000,499.400,114.000,485.878z">
<GeometryDrawing.Brush>
<LinearGradientBrush StartPoint="114,389.862" EndPoint="392,389.862" MappingMode="Absolute" SpreadMethod="Pad">
<GradientStop Color="Black" Offset="0" />
<GradientStop Color="#FFDADADA" Offset="0.082" />
<GradientStop Color="#FF282828" Offset="0.854" />
<GradientStop Color="White" Offset="0.949" />
<GradientStop Color="Black" Offset="1" />
</LinearGradientBrush>
</GeometryDrawing.Brush>
</GeometryDrawing>
</DrawingGroup>
</DrawingBrush.Drawing>
<DrawingBrush.RelativeTransform>
<RotateTransform CenterX=".5" CenterY=".5" Angle="90"/>
</DrawingBrush.RelativeTransform>
</DrawingBrush>
You can use the Background property inline with the UniformGrid.
Try the code below:
<UniformGrid Background="{StaticResource SteelBrush_Vert}"
Rows="1"
Columns="1"
Height="75" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Grid.Row="2"/>

WPF radio button icon change (the circle itself)

I would like to have a group of radio buttons which the circles for un-selected and selected mode are changed to circle icons that I designed.
It that possible to do that in WPF?
Thanks in advance
Create a style and override the default template for RadioButtons. Something like this:
<Window.Resources>
<Style TargetType="RadioButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RadioButton}">
<BulletDecorator Background="Transparent">
<BulletDecorator.Bullet>
<Grid Width="13" Height="13">
<Ellipse x:Name="Border" StrokeThickness="2">
<Ellipse.Stroke>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Green" Offset="0" />
<GradientStop Color="Pink" Offset="1" />
</LinearGradientBrush>
</Ellipse.Stroke>
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="Orange" />
<GradientStop Color="Red"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Ellipse x:Name="CheckMark"
Margin="4"
Visibility="Collapsed">
<Ellipse.Fill>
<SolidColorBrush Color="Purple" />
</Ellipse.Fill>
</Ellipse>
</Grid>
</BulletDecorator.Bullet>
<ContentPresenter Margin="4,0,0,0"
VerticalAlignment="Center"
HorizontalAlignment="Left"
RecognizesAccessKey="True" />
</BulletDecorator>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
Yes, of course, it is possible. You can override default ControlTemplate and create style for your own radiobutton. Here is an example, you can also use Style Snooper to see the WPF built-in radio button style (a big piece of XAML code:) )

Transform not working in GeomectryDrawing in xaml

<Style x:Key="ICON" TargetType="Rectangle">
<Setter Property="Fill">
<Setter.Value>
<DrawingBrush TileMode="None">
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="Gray" 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>
<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="#FF657783" Offset="0"/>
<GradientStop Color="White" Offset="0.5"/>
<GradientStop Color="#FF2C4758" Offset="1"/>
</LinearGradientBrush>
</Pen.Brush>
<Pen.DashStyle>
<DashStyle/>
</Pen.DashStyle>
</Pen>
</GeometryDrawing.Pen>
</GeometryDrawing>
<DrawingGroup.Transform>
<TranslateTransform X="0.2" Y="0.2" />
</DrawingGroup.Transform>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</Setter.Value>
</Setter>
</Style>
The inner icon should dominate the outer icon but here, its happening the reverse. My initial guess is that transform is not working but on further observation, I feel that the code is written correctly. Can anyone point out whats the mistake here?
It's working, but you should adjust it properties a little. So the code should look like this. Also I've added code for scaling romb.
<DrawingGroup.Transform>
<TransformGroup>
<TranslateTransform X="12" Y="12" />
<ScaleTransform ScaleX="0.75" ScaleY="0.75" />
</TransformGroup>
</DrawingGroup.Transform>

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>

WPF enabling transparency

Going off the how-to from MSDN here, I have the following code that displays a reflection right below an element.
How can I enable transparency on the reflection only, so what is behind the window shows through the reflection?
<Window x:Class="XAMLViewTests.AboutWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="AboutWindow" ResizeMode="CanResizeWithGrip" SizeToContent="WidthAndHeight" Width="400"
AllowsTransparency="True" WindowStyle="None" WindowStartupLocation="CenterOwner" Background="Transparent">
<Window.Resources>
<Style TargetType="TextBlock" x:Key="formattedText">
<Setter Property="FontFamily" Value="Calibri"></Setter>
<Setter Property="FontSize" Value="20"></Setter>
<Setter Property="Padding" Value="5,5,5,5"></Setter>
<Setter Property="TextWrapping" Value="Wrap"></Setter>
</Style>
<LinearGradientBrush x:Key="linearGradBrush">
<LinearGradientBrush.GradientStops>
<GradientStop Offset="0.0"
Color="White"></GradientStop>
<GradientStop Offset="1.0"
Color="LightSlateGray"></GradientStop>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Window.Resources>
<StackPanel Orientation="Vertical" Background="{StaticResource linearGradBrush}">
<Button Width="50" HorizontalAlignment="Right" Click="ReturnToPreviousWindow" Background="White">Return</Button>
<TextBlock Style="{StaticResource formattedText}" x:Name="textBlock" HorizontalAlignment="Center">
Some text here.
</TextBlock>
<!-- Reflection visual courtesy of MS How-To at https://msdn.microsoft.com/en-us/library/aa970263(v=vs.110).aspx -->
<Rectangle Height="1" Fill="Gray" HorizontalAlignment="Stretch"></Rectangle>
<Rectangle Height="{Binding ElementName=textBlock, Path=ActualHeight}"
Width="{Binding ElementName=textBlock, Path=ActualWidth}"
HorizontalAlignment="{Binding ElementName=textBlock, Path=HorizontalAlignment}">
<Rectangle.Fill>
<VisualBrush Stretch="None" Visual="{Binding ElementName=textBlock}">
<VisualBrush.RelativeTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="-1"></ScaleTransform>
<TranslateTransform Y="1"></TranslateTransform>
</TransformGroup>
</VisualBrush.RelativeTransform>
</VisualBrush>
</Rectangle.Fill>
<Rectangle.OpacityMask>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Color="#FF000000" Offset="0.0"></GradientStop>
<GradientStop Color="#33000000" Offset="0.5"></GradientStop>
<GradientStop Color="#00000000" Offset="0.9"></GradientStop>
</LinearGradientBrush>
</Rectangle.OpacityMask>
<Rectangle.Effect>
<BlurEffect Radius="2.5"></BlurEffect>
</Rectangle.Effect>
</Rectangle>
</StackPanel>
</Window>
The linear gradient brush has 100% opacity and is applied to the entire stackpanel which contains the element you want transparency on. I reformatted it a bit and split out the stackpanel. Probably needs more work, but this should demonstrate the concept. Note the second gradient brush with a 0.5 (50%) opacity applied to the second stackpanel.
<Window x:Class="XAMLViewTests.AboutWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="AboutWindow" ResizeMode="CanResizeWithGrip" SizeToContent="WidthAndHeight" Width="400"
AllowsTransparency="True" WindowStyle="None" WindowStartupLocation="CenterOwner" Background="Transparent">
<Window.Resources>
<Style TargetType="TextBlock" x:Key="formattedText">
<Setter Property="FontFamily" Value="Calibri"></Setter>
<Setter Property="FontSize" Value="20"></Setter>
<Setter Property="Padding" Value="5,5,5,5"></Setter>
<Setter Property="TextWrapping" Value="Wrap"></Setter>
</Style>
<LinearGradientBrush x:Key="linearGradBrush">
<LinearGradientBrush.GradientStops>
<GradientStop Offset="0.0"
Color="White"></GradientStop>
<GradientStop Offset="1.0"
Color="LightSlateGray"></GradientStop>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="linearGradBrushWithTransparency" Opacity="0.5">
<LinearGradientBrush.GradientStops>
<GradientStop Offset="0.0"
Color="White"></GradientStop>
<GradientStop Offset="1.0"
Color="LightSlateGray"></GradientStop>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Window.Resources>
<StackPanel Orientation="Vertical" Background="{StaticResource linearGradBrushWithTransparency}">
<StackPanel Orientation="Vertical" Background="{StaticResource linearGradBrush}">
<Button Width="50" HorizontalAlignment="Right" Click="ReturnToPreviousWindow" Background="White">Return</Button>
<TextBlock Style="{StaticResource formattedText}" x:Name="textBlock" HorizontalAlignment="Center">
Some text here.
</TextBlock>
<!-- Reflection visual courtesy of MS How-To at https://msdn.microsoft.com/en-us/library/aa970263(v=vs.110).aspx -->
<Rectangle Height="1" Fill="Gray" HorizontalAlignment="Stretch"></Rectangle>
</StackPanel>
<Rectangle Height="{Binding ElementName=textBlock, Path=ActualHeight}"
Width="{Binding ElementName=textBlock, Path=ActualWidth}"
HorizontalAlignment="{Binding ElementName=textBlock, Path=HorizontalAlignment}"
Opacity=".5">
<Rectangle.Fill>
<VisualBrush Stretch="None" Visual="{Binding ElementName=textBlock}">
<VisualBrush.RelativeTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="-1"></ScaleTransform>
<TranslateTransform Y="1"></TranslateTransform>
</TransformGroup>
</VisualBrush.RelativeTransform>
</VisualBrush>
</Rectangle.Fill>
<Rectangle.OpacityMask>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Color="#FF000000" Offset="0.0"></GradientStop>
<GradientStop Color="#33000000" Offset="0.5"></GradientStop>
<GradientStop Color="#00000000" Offset="0.9"></GradientStop>
</LinearGradientBrush>
</Rectangle.OpacityMask>
<Rectangle.Effect>
<BlurEffect Radius="2.5"></BlurEffect>
</Rectangle.Effect>
</Rectangle>
</StackPanel>
</Window>

Resources