Binding window's background - wpf

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.....

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

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>

Triggering the style of a WPF button when a dependency property changes

I've created a button control template where I want to change the color of the button depending on the mode of the button (whether its in Go mode or Stop mode). The XAML looks like :
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Ellipse x:Name="innerCircle" RenderTransformOrigin=".5,.5">
<Ellipse.RenderTransform>
<ScaleTransform ScaleX=".8" ScaleY=".8"/>
</Ellipse.RenderTransform>
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStopCollection>
<GradientStop Offset="0" Color="Green"/>
<GradientStop Offset="1" Color="Transparent"/>
</GradientStopCollection>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Viewbox>
<ContentPresenter Margin="{TemplateBinding Padding}"/>
</Viewbox>
</Grid>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsGo}" Value="True">
<Setter TargetName="outerCircle" Property="Fill">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStopCollection >
<GradientStop Offset="0" Color="White"/>
<GradientStop Offset="1" Color="Red"/>
</GradientStopCollection>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter TargetName="innerCircle" Property="Fill">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStopCollection>
<GradientStop Offset="0" Color="Red"/>
<GradientStop Offset="1" Color="Transparent"/>
</GradientStopCollection>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Grid.Resources>
<Button Background="Transparent" Content="STOP" Padding="10" Template="{StaticResource buttonTemplate}" Height="84" Width="87" Click="Button_Click"></Button>
</Grid>
In my DataTrigger i have a binding to a IsGo DP property which i have defined in the code behind (of type boolean). I have a click handler which toggles the state of this DP in the code behind :
/// <summary>
/// Interaction logic for GoButton.xaml
/// </summary>
public partial class GoButton
{
public GoButton()
{
InitializeComponent();
}
public static readonly DependencyProperty IsGOProperty = DependencyProperty.Register("IsGo", typeof(Boolean), typeof(GoButton), new PropertyMetadata(false));
public Boolean IsGo
{
get { return (Boolean)GetValue(IsGOProperty); }
set { SetValue(IsGOProperty, value); }
}
private void Button_Click(object sender, RoutedEventArgs e)
{
IsGo = !IsGo;
}
}
However, when i click my button, nothing happens - although the click handler code executes and toggles the DP property, the colour of the button stays green and doesn't change to red. Any ideas what i'm doing wrong ?
thanks
You need to trigger the dependency property to refresh. You can do that by implementing INotifyPropertyChanged, removing IsGOProperty and then implementing IsGo like this:
private bool _isgo = false;
public bool IsGo {
get
{
return _isgo;
}
set
{
_isgo = value;
PropertyChanged(new PropertyChangedEventArgs("IsGo");
}
}
Your TemplatedParent is (I'm guessing) the button you're templating. The codebehind where you've defined your property most likely isn't a control derived from button, so I'm guessing your trigger's binding is incorrect...
If you could post the rest of your XAML and/or confirm which codebehind your property is in, this could be confirmed.
EDIT: Your comment confirms my theory: you're binding to TemplatedParent but the property isn't on TemplatedParent, it's on your usercontrol. The easist solution is to add a x:Name="root" tag to your UserControl's root element, and then change the trigger's binding to {Binding ElementName=root, Path=IsGo}.

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>

Template Binding to background and foreground colors?

I'm building a simple ControlTemplate for a Button. I want to draw a 2 color gradient, and bind the two colors so I don't need to hard code them in the template. But since Background and Foreground are Brushes and not just Colors, I'm not sure this will work.
Can anyone tell me if there is a good way to do this? it seems simple enough. Thanks.
<ControlTemplate x:Key="ElipseButton" TargetType="Button">
<Ellipse>
<Ellipse.Fill>
<RadialGradientBrush RadiusX="1" RadiusY="1" GradientOrigin="0.7,0.8">
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="Black" Offset="1"/>
</RadialGradientBrush>
</Ellipse.Fill>
</Ellipse>
</ControlTemplate>
I want to replace the 'Black' and 'White' colors with TemplateBindings.
You can use attached properties to add some new Color properties that you can use on Button:
public class ColorExtensions
{
public static readonly DependencyProperty ColorFrontProperty = DependencyProperty.RegisterAttached(
"ColorFront",
typeof(Color),
typeof(ColorExtensions),
new UIPropertyMetadata(Colors.White));
public static Color GetColorFront(DependencyObject target)
{
return (Color)target.GetValue(ColorFrontProperty);
}
public static void SetColorFront(DependencyObject target, Color value)
{
target.SetValue(ColorFrontProperty, value);
}
public static readonly DependencyProperty ColorBackProperty = DependencyProperty.RegisterAttached(
"ColorBack",
typeof(Color),
typeof(ColorExtensions),
new UIPropertyMetadata(Colors.Black));
public static Color GetColorBack(DependencyObject target)
{
return (Color)target.GetValue(ColorBackProperty);
}
public static void SetColorBack(DependencyObject target, Color value)
{
target.SetValue(ColorBackProperty, value);
}
}
You can then set these on any instance and access them in your template using normal Bindings (TemplateBindings won't work here):
<Button Content="Click Me" local:ColorExtensions.ColorFront="Red">
<Button.Template>
<ControlTemplate TargetType="Button">
<Ellipse>
<Ellipse.Fill>
<RadialGradientBrush RadiusX="1" RadiusY="1" GradientOrigin="0.7,0.8">
<GradientStop Color="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:ColorExtensions.ColorFront)}" Offset="0"/>
<GradientStop Color="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:ColorExtensions.ColorBack)}" Offset="1"/>
</RadialGradientBrush>
</Ellipse.Fill>
</Ellipse>
</ControlTemplate>
</Button.Template>
</Button>
Personally, I would just put the entire Brush into your template. This gives you much more control, later, as it allows you to change (via template changes) the brush from a radial gradient to a linear gradient, etc.

Resources