WPF Binding Color Property - wpf

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

Related

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>

Adding Constant to resources

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>

Binding window's background

I want to bind the background of a window to some string property, such that I'll have a gradient background in different colors when the property changes:
<Window.Background>
<LinearGradientBrush>
<LinearGradientBrush.GradientStops>
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="{Binding Source={RelativeSource Mode=Self},
Path=backgroud_color}" Offset="1"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Window.Background>
code behind:
public event PropertyChangedEventHandler PropertyChanged;
private string _backgroud_color;
public string backgroud_color
{
get { return _backgroud_color; }
set
{
_backgroud_color = value;
OnPropertyChanged("backgroud_color");
}
}
public void OnPropertyChanged(string property_name)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(property_name));
}
but the background does not change at all.
What is the problem?
The problem is the RelativeSource in the Binding. It'll refer to the GradientStop which doesn't have a backgroud_color Property. Have you set the DataContext for the Window? In that case, you can just bind to backgroud_color like this
<Window.Background>
<LinearGradientBrush>
<LinearGradientBrush.GradientStops>
<GradientStop Color="White" Offset="0.5"/>
<GradientStop Color="{Binding Path=backgroud_color}" Offset="1" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Window.Background>
Code behind
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
}
You can go through the following link......might find it good to learn and understand basics.....

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