Adding Constant to resources - wpf

I have a brush defined as a constant in code that I want to add to the resources tag of a DataGrid I have defined in XAML with a specific key.
How do I do this?
I need to add the existing brush with the key since Im overriding the look of a highlighted row:
<DataGrid.Resources>
<LinearGradientBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#FFD6A4" Offset="0"/>
<GradientStop Color="#FFAB3F" Offset="1"/>
</LinearGradientBrush>
</DataGrid.Resources>
The brush I want to use without having to redefine it is:
public static class Colours
{
public static LinearGradientBrush HighlightedRow { get; private set; }
static Colours()
{
HighlightedRow = new LinearGradientBrush(Color.FromRgb(255, 214, 164), Color.FromRgb(255, 171, 63), 90);
}
}

You can do this in code behind:
myDataGrid.Resources.Add(SystemColors.HighlightBrushKey, Colours.HighlightedRow);
Or in XAML only:
If you had the two gradient stop colors as resources, then you could reference them dynamically in XAML.
<Color x:Key="Color1">#FFFF0000</Color>
<Color x:Key="Color2">#FFFF3300</Color>
<DataGrid.Resources>
<LinearGradientBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="{DynamicResource Color1}" Offset="0"/>
<GradientStop Color="{DynamicResource Color2}" Offset="1"/>
</LinearGradientBrush>
</DataGrid.Resources>

Related

WPF Binding Color Property

I am very new to WPF and working through a few sample controls and trying to adapt them in order to familiarize myself on how things work.
My current task is I have a LinearGradientBrush code below
<LinearGradientBrush x:Key="ThumbBrush" StartPoint="0,0" EndPoint="1,0">
<GradientStop Offset="0" Color="#c1dbe8"/>
<GradientStop Offset="0.5" Color="#008fc7"/>
<GradientStop Offset="1" Color="#066caa"/>
</LinearGradientBrush>
I would like to convert this to a property so that colours can be amended. My thought was that I could simply create a Property for each Color
public Color MyThumbColor1 { get; set; }
public Color MyThumbColor2 { get; set; }
public Color MyThumbColor3 { get; set; }
Then bind each color to the respective GradientStop
<GradientStop Offset="0" Color="{Binding MyThumbColor1}"/>
<GradientStop Offset="0.5" Color="{Binding MyThumbColor1}"/>
<GradientStop Offset="1" Color="{Binding MyThumbColor1}"/>
This isn't working therefore any guidance on how to bind a color Property would be much appreciated
It appears I forgot to include
this.DataContext = this;
just after InitializeComponent(); on the NewControl.xaml.cs file

WPF Control OverrideMetadata: specify default value to come from resource

I would like to specify a resource as a default value for my control for the BorderBrushProperty. The reason being the brush is a LinearGradientBrush which I defined in XAML. So I'm looking for something like this in my static CTOR (3rd line):
static Gauge()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof (Gauge), new FrameworkPropertyMetadata(typeof (Gauge)));
BorderThicknessProperty.OverrideMetadata(typeof (Gauge), new FrameworkPropertyMetadata(new Thickness(16)));
BorderBrushProperty.OverrideMetadata(typeof (Gauge), new FrameworkPropertyMetadata("OuterFrameStroke"));
}
This is what my XAML looks like (in themes\generic.xaml):
<LinearGradientBrush x:Key="OuterFrameStroke" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF636060" Offset="1" />
<GradientStop Color="#FF5F5C5C" Offset="0" />
<GradientStop Color="#FFEEDEDE" Offset="0.35" />
<GradientStop Color="#FFA09595" Offset="0.705" />
</LinearGradientBrush>
Well, should have thought 2 seconds longer. Of course I can set this default property in my template
<Style TargetType="gauge:Gauge">
<Setter Property="BorderBrush">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFA3AFD6" Offset="0.321" />
<GradientStop Color="#FF8399A9" Offset="0.674" />
<GradientStop Color="#FF718597" Offset="0.375" />
<GradientStop Color="#FF617584" Offset="1" />
</LinearGradientBrush>
</Setter.Value>
</Setter>

How to create an array of linear gradient brushes in xaml using static resource?

I am trying to create an array of gradient brushes in xaml but I would like to point each array element back to a static resource that is the gradient brush. So, far I've been unable to achieve this. Can someone provide guidance on how I might accomplish this?
I want to add them to an x:Array but point to the resource rather than having to re-define the brushes as I've had to do here. I use the brushes in several places in addition to an array of them so I only want to define the brushes once.
<LinearGradientBrush x:Key="OrangeLinearGradientBrush" StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Offset="0" Color="#FFF7941D" />
<GradientStop Offset="1" Color="#FFF26522" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="RedLinearGradientBrush" StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Offset="0" Color="#F26263" />
<GradientStop Offset="1" Color="#B80303" />
</LinearGradientBrush>
<x:Array x:Key="BrushArray" Type="LinearGradientBrush">
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Offset="0" Color="#FFF7941D" />
<GradientStop Offset="1" Color="#FFF26522" />
</LinearGradientBrush>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Offset="0" Color="#F26263" />
<GradientStop Offset="1" Color="#B80303" />
</LinearGradientBrush>
</x:Array>
You may use StaticResourceExtensions:
<x:Array x:Key="BrushArray" Type="LinearGradientBrush">
<StaticResourceExtension ResourceKey="OrangeLinearGradientBrush"/>
<StaticResourceExtension ResourceKey="RedLinearGradientBrush"/>
</x:Array>

Transparent system color in gradient (WPF)

How to achieve such effect in XAML:
<LinearGradientBrush x:Key="BrightSeparatorGradient" StartPoint="0.0, 0.5" EndPoint="1.0, 0.5">
<GradientStop Offset="0.0" Color="{StaticResource {x:Static SystemColors.ControlLightColorKey}}" /> <!-- But fully transparent -->
<GradientStop Offset="0.5" Color="{StaticResource {x:Static SystemColors.ControlLightColorKey}}" />
<GradientStop Offset="1.0" Color="{StaticResource {x:Static SystemColors.ControlLightColorKey}}" /> <!-- But fully transparent -->
</LinearGradientBrush>
I've tried to create two brushes with appropriate color and Opacity set, respectively, to 0.0 and 1.0, but the compiler refused to take Brush as a Color (what is quite logic, on a second thought :)).
Best regards -- Spook.
I would create a MarkupExtension that takes a Color and returns the Color with the specified opacity:
public class OpacityExtension : MarkupExtension
{
private readonly Color color;
public byte Opacity { get; set; } // defaults to 0, so you don't have
// to set it for the color to be transparent
public OpacityExtension(Color color)
{
this.color = color;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return Color.FromArgb(Opacity, color.R, color.G, color.B);
}
}
And then you use it like so:
<LinearGradientBrush x:Key="BrightSeparatorGradient" StartPoint="0.0, 0.5" EndPoint="1.0, 0.5">
<GradientStop Offset="0" Color="{lcl:Opacity {StaticResource {x:Static SystemColors.ControlLightColorKey}}}" />
<GradientStop Offset=".5" Color="{StaticResource {x:Static SystemColors.ControlLightColorKey}}" />
<GradientStop Offset="1" Color="{lcl:Opacity {StaticResource {x:Static SystemColors.ControlLightColorKey}}}" />
</LinearGradientBrush>
Spook,
Why the following doesn't work for you?
<LinearGradientBrush x:Key="BrightSeparatorGradient" StartPoint="0.0, 0.5" EndPoint="1.0, 0.5">
<GradientStop Offset="0.0" Color="Transparent" />
<GradientStop Offset="0.5" Color="{StaticResource {x:Static SystemColors.ControlLightColorKey}}" />
<GradientStop Offset="1.0" Color="Transparent" />
</LinearGradientBrush>

Using a StaticResource SolidColorBrush to define the Gradient Stop Colors

I am creating some wpf resource dictionaries with all the styles for an application! I have a few LinearGradientBrushes, where the color is set directly in the LinearGradientBrush reference as GradientStops. However, I want to have a predefined set of colors that I can use a a reference for each GradientStop, so that changing the color scheme for the application is a matter of changing the values of the SolidColorBrushes:
<SolidColorBrush Color="#5A5A5A" x:Key="colorbrushMedium" />
<SolidColorBrush Color="#222222" x:Key="colorbrushDark" />
<LinearGradientBrush>
<GradientStop Color="{StaticResource colorbrushMedium}"/>
<GradientStop Color="{StaticResource colorbrushDark}" Offset="1"/>
</LinearGradientBrush>
With the code example above, I am getting the following error:
Cannot convert the value in attribute 'Color' to object of type 'System.Windows.Media.Color'. '#5A5A5A' is not a valid value for property 'Color'.
The line it refers to is the line where <GradientStop Color="{StaticResource colorbrushMedium}"/> is defined.
Any ideas?
Ok, I found the problem:
Using Color and not SolidColorBrush..
<Color x:Key="colorbrushMedium">#FF5A5A5A</Color>
<Color x:Key="colorbrushDark">#FF222222</Color>
<LinearGradientBrush>
<GradientStop Color="{StaticResource colorbrushMedium}"/>
<GradientStop Color="{StaticResource colorbrushDark}" Offset="1"/>
</LinearGradientBrush>
This seems to solve my problem!
Use Binding to reference the color both in SolidColorBrush and in LinearGradientBrush:
<SolidColorBrush x:Key="stop1" Color="#FF5A5A5A"/>
<SolidColorBrush x:Key="stop2" Color="#FF222222"/>
<LinearGradientBrush x:Key="gradient">
<GradientStop Color="{Binding Source={StaticResource stop1},Path=Color}" Offset="0"/>
<GradientStop Color="{Binding Source={StaticResource stop2},Path=Color}" Offset="1"/>
</LinearGradientBrush>

Resources