How to use application's resource from ControlTemplate? - wpf

I get this error
'disable_glow' name cannot be found in the name scope of 'System.Windows.Controls.ControlTemplate'.
when trying to do this:
Application's resources:
<LinearGradientBrush Opacity="0.0" StartPoint="0,0"
EndPoint="0,1" x:Key="disable_glow" x:Name="disable_glow">
<GradientStop Offset="0.0" Color="#4D4D4D" />
<GradientStop Offset="0.1" Color="#404040" />
<GradientStop Offset="1.0" Color="#2E2E2E" />
</LinearGradientBrush>
in here:
Same place, in the ControlTemplate of the control Style:
<Border CornerRadius="4">
<Border.Background>
<DrawingBrush>
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="{StaticResource disable_glow}">
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0,0,1,1"/>
</GeometryDrawing.Geometry>
</GeometryDrawing>
...
When I use either StaticResource or DynamicResource keyword I get the same error.
So how to use it correctly?

You don't need to set the x:Name attribute on your LinearGradientBrush, if it's in a ResourceDictionary (i.e. a Resources collection). You just need to set x:Key to be able to access it.
The error you are getting would not be produced by the Brush="{StaticResource disable_glow}" code. If the resources wasn't found it would say something like "Resource not found". It sounds like you are/were trying to access it by name.
You would need to ensure that your LinearGradientBrush is defined before your ControlTemplate.

Related

Create custom shape consisting of multiple single lines

i want to create a simple cross, that consists of two lines. The lines should have different colors. I've created a class that inherits form Shape. This class contains the two lines and computes the coordinates of the lines. I've read that i have to implement the DefiningGeometry property if i inherit from Shape. But how can i return both lines in the get section of that property?
Thanks in advance.
It sounds like you could use the CombinedGeometry Class to combine your lines together... the only thing is that you'll need to use LineGeometry classes instead of Lines. You could do something like this (from the linked CombinedGeometry page on MSDN):
<Path Stroke="Black" StrokeThickness="1" Fill="#CCCCFF">
<Path.Data>
<!-- Combines two geometries using the XOR combine mode. -->
<CombinedGeometry GeometryCombineMode="Xor">
<CombinedGeometry.Geometry1>
<EllipseGeometry RadiusX="50" RadiusY="50" Center="75,75" />
</CombinedGeometry.Geometry1>
<CombinedGeometry.Geometry2>
<EllipseGeometry RadiusX="50" RadiusY="50" Center="125,75" />
</CombinedGeometry.Geometry2>
</CombinedGeometry>
</Path.Data>
</Path>
Of course, you'd want to replace these EllipseGeometry objects with LineGeometry objects, but that shouldn't be difficult as they have similar properties.
UPDATE >>>
Unfortunately, I don't think that you can use a CombinedGeometry object that contains geometries of different colours... the whole shape would have to be painted with one Brush. However, you could fake two colours with cleverly positioned GradientStops. Also, as #Clemens mentioned, perhaps a GeometryGroup would be easier for you to use... try something like this:
<Path StrokeThickness="5" Fill="Blue" HorizontalAlignment="Center" VerticalAlignment="Center">
<Path.Data>
<GeometryGroup>
<LineGeometry StartPoint="50,0" EndPoint="50,100" />
<LineGeometry StartPoint="0,50" EndPoint="100,50" />
</GeometryGroup>
</Path.Data>
<Path.Stroke>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<GradientStop Color="LightGreen" Offset="0" />
<GradientStop Color="LightGreen" Offset="0.475" />
<GradientStop Color="Red" Offset="0.475" />
<GradientStop Color="Red" Offset="0.525" />
<GradientStop Color="LightGreen" Offset="0.525" />
<GradientStop Color="LightGreen" Offset="0" />
</LinearGradientBrush>
</Path.Stroke>
</Path>
This Brush will appear as if it were actually different colours on the two lines:
Then all you'll need to do is to convert this into C# to return it from the DefiningGeometry property. Please use the examples from the linked pages and the GeometryGroup class page on MSDN to help you with this.
You may draw two differently colored lines by means of two GeometryDrawings in a DrawingBrush that fills a Rectangle:
<Rectangle Width="20" Height="20">
<Rectangle.Fill>
<DrawingBrush>
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing Geometry="M0,-10 L0,10">
<GeometryDrawing.Pen>
<Pen Brush="Blue" Thickness="3"/>
</GeometryDrawing.Pen>
</GeometryDrawing>
<GeometryDrawing Geometry="M-10,0 L10,0">
<GeometryDrawing.Pen>
<Pen Brush="Red" Thickness="3"/>
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</Rectangle.Fill>
</Rectangle>

Solid transparent line in WPF gradient

I am trying to draw a transparent line in a solid block using a gradient:
<Grid>
<Border Margin="-102,-27,102,27">
<Border.Background>
<LinearGradientBrush EndPoint="517,160" StartPoint="0,160" MappingMode="Absolute">
<GradientStop Color="#FF2DBCF2" Offset="0"/>
<GradientStop Color="#FF2DBCF2" Offset="1"/>
<GradientStop Color="#002DBCF2" Offset="0.0091" />
<GradientStop Color="#FF2DBCF2" Offset="0.009"/>
<GradientStop Color="#002DBCF2" Offset="0.015"/>
<GradientStop Color="#FF2DBCF2" Offset="0.0151"/>
</LinearGradientBrush>
</Border.Background>
</Border>
</Grid>
The problem is that on the edges of the gap in the solid colour block there is a faint fading effect which makes the edge slightly less than crisp. Is there a way to get rid of this faint fading? I just can't seem to find a way around it.
You may use something like the following DrawingBrush for the background:
<Border Margin="-102,-27,102,27">
<Border.Background>
<DrawingBrush>
<DrawingBrush.Drawing>
<GeometryDrawing Brush="#FF2DBCF2">
<GeometryDrawing.Geometry>
<GeometryGroup>
<RectangleGeometry Rect="0,0,0.01,1"/>
<RectangleGeometry Rect="0.015,0,0.985,1"/>
</GeometryGroup>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
</Border.Background>
</Border>
The only way to get a sharp line in the background is to use an ImageBrush or DrawingBrush as background instead of a LinearGradientBrush
I can't work out a complete example right now, but this should get you started on how to implement a DrawingBrush as background.
<Border.Background>
<DrawingBrush TileMode="Tile" Stretch="None" Viewport="0,0,20,20" ViewportUnits="Absolute">
<DrawingBrush.Drawing>
<GeometryDrawing>
<GeometryDrawing.Pen>
<Pen Brush="White"/>
</GeometryDrawing.Pen>
<GeometryDrawing.Geometry>
<LineGeometry StartPoint="0.3,0"
EndPoint="0.3,20"/>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
<Border.Background>

WPF change dynamicresource in codebehind

The standard RadioButton does not support setting the color of the ellipse. So, I took a radiobutton template from this location as a basis for a custom RadioButton:
RadioButton Styles and Templates
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource ControlLightColor}" />
<GradientStop Color="{DynamicResource ControlMediumColor}" Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
ControlLightColor and ControlMediumColor are defined as:
<Color x:Key="ControlLightColor">#ffff9a</Color>
<Color x:Key="ControlMediumColor">#ffff9a</Color>
Which gives us a yellow-ish ellipse.
How can I alter this color in the codebehind?
Regards,
Michel
Create a style by following this:
Creating a Style in code behind
then assign it to your element.Style
You can also access resources by
Resources["mykey"]
Solution:
<Ellipse x:Name="Border" StrokeThickness="1" Fill="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.RadioButtonColor}">
Public ReadOnly Property RadioButtonColor() As SolidColorBrush
Get
Dim solidColorBrush As SolidColorBrush
If MyBusinessLogic Then
solidColorBrush = _radioButtonNotRequiredBrush
Else
solidColorBrush = _radioButtonRequiredBrush
End If
Return solidColorBrush
End Get
End Property
Thumbs up for JRB for thinking along.

Property path can't find reference

What's the syntax for the property path to find the color property of the second gradientStop?
<Rectangle.Fill>
<RadialGradientBrush>
<GradientStop Color="White" Offset="0" />
<GradientStop Color="#FFD0D0D0" Offset="0.992" />
</RadialGradientBrush>
</Rectangle.Fill>
I tried New PropertyPath("Fill.RadialGradientBrush.GradientStops[1].Color") but it could find the color property.
In this case, the Fill property is the RadialGradientBrush. The brush is not a member of Fill.
Try PropertyPath("Fill.GradientStops[1].Color")
I guess it should be :
(Fill as RadialGradientBrush).GradientStops[1].Color
Because RadialGradientBrush is not a property, but a class

Vignette effect without coding

Is there any method exist to create vignetting/frame effect on picturebox, ie another picturebox with png image as overlay/mask? I don't want to see sharp edges between picture and background.
You could use OpacityMask : something like
<Image Width="200" Source="C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.jpg">
<Image.OpacityMask>
<RadialGradientBrush>
<GradientStop Offset="0.8" Color="#ffff"></GradientStop>
<GradientStop Offset="1" Color="#0fff"></GradientStop>
</RadialGradientBrush>
</Image.OpacityMask>
</Image>
would give a vignette effect.

Resources