WPF: Binding to a resource via code

M

Michaela Meier

Hi,

I'm trying to bind the foreground color of a control to a resource ...
by code.

e.g. so far my XAML includes
<Window.Resources>
<SolidColorBrush x:Key="Color1" Color="#FFFFFFFF"/>
<SolidColorBrush x:Key="Color2" Color="#FF808080"/>
<SolidColorBrush x:Key="Color3" Color="#FF00FF00" />

But how do i do this in code?

Currently I am using hardcoded colors like this (which works)

private Brush _mycolor=Brushes.Green;
public Brush MyColor { get; set;}

private string _mytext="Hello, World";
public string MyText { get; set;}

<TextBlock Text="{Binding Path=MyText}" Foreground="{Binding
Path=MyColor}"/>


My first attempts at converting this into resources kinda failed *g*

private string _mycolorresource="Color3";
public string MyColorResource
{ get; set;}

private string _mytext="Hello, World";
public string MyText
{ get; set;}

<TextBlock Text="{Binding Path=MyText}" Foreground="{Binding
Path=MyColorResource}"/>

How is this done correctly?

TIA
 
A

Alexander Mueller

Michaela said:
Hi,

I'm trying to bind the foreground color of a control to a resource ...
by code.

e.g. so far my XAML includes
<Window.Resources>
<SolidColorBrush x:Key="Color1" Color="#FFFFFFFF"/>
<SolidColorBrush x:Key="Color2" Color="#FF808080"/>
<SolidColorBrush x:Key="Color3" Color="#FF00FF00" />
</Window.Resources>
<TextBlock Text="Hello, World!" Foreground="{DynamicResource Color3}"/

But how do i do this in code?

Currently I am using hardcoded colors like this (which works)

private Brush _mycolor=Brushes.Green;
public Brush MyColor { get; set;}

This will not work: _mycolor and MyColor are not connected.
either write:

//using an undeclared autovariable, omitting _mycolor
//ctor
{
this.MyColor = Brushes.Green;
}
public Brush MyColor { get; set;}

or write:

//using the explicitly declared variable _mycolor
private Brush _mycolor = Brushes.Green;
public Brush MyColor
{
get {return _mycolor;}
set {_mycolor = value;}
}



private string _mytext="Hello, World";
public string MyText { get; set;}

Same thing here: _mytext and MyText are two different storages
for string data...
<TextBlock Text="{Binding Path=MyText}" Foreground="{Binding
Path=MyColor}"/>

If you bind to a public Property of a XAML-class,
you need to set the DataContext of the class-instance to the
instance itself, which usually is done in the ctor:

this.DataContext = this;

Then the Path "MyText" is located in the properties of the the very
class - and the Binding works if there is a public Property named
"MyText", which btw needs a setter and a getter.
My first attempts at converting this into resources kinda failed *g*


<TextBlock Text="{Binding Path=MyText}" Foreground="{Binding
Path=MyColorResource}"/>

You bind to a DynamicResource by using the "{DynamicResource
resourceKeyName}"-syntax, not by using the {Binding ...}-syntax.
E.g.

<TextBlock Background="{DynamicResource ColorDyn}">

In order to change the value of the DynamicResource, you simple need to
assign a new value to the resource in C#-code:

this.Resources["ColorDyn"] = Brushes.Blue;

where "ColorDyn" specifies the key of the resource.
The DataType of the new value must of course correspond to the
DataType expected by the attributes you bind the resource to.
If you bind to "Background" then you want a Brush (not a string
with a color's name...).
The string-thing works in XAML because it has its default-converters
that make a brush from a string for you behind the scenes.
They don't apply in C#-code.

Have a look at the pieces of code, below, maybe it helps:

MfG,
Alex

XAML
-------------------------------------------
<Window x:Class="WpfApplication1.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window2" Height="150" Width="300">
<Window.Resources>
<SolidColorBrush x:Key="ColorDyn" Color="#FFFFFFFF" />
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2"
Margin="5" Name="textBlock1" VerticalAlignment="Center"
Text="Enter ARGB as 8-digit-Hex"/>
<TextBox Grid.Row="1" Grid.Column="0" Margin="5" Name="textBox1"
VerticalAlignment="Center" />
<Button Grid.Row="1" Grid.Column="1" Margin="5" Name="button1"
Content="Apply ARGB" VerticalAlignment="Center"
Click="button1_Click" />
<DockPanel Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2"
Margin="5" Name="dockPanel1"
Background="{DynamicResource ColorDyn}">
<TextBlock DockPanel.Dock="Top" Name="TbHint"
VerticalAlignment="Center" HorizontalAlignment="Center"
Text="ARGB-Value entered is invalid or empty"
Foreground="Red" Background="Yellow"
Visibility="Hidden"/>
</DockPanel>
</Grid>
</Window>



C#
-------------------------------------------
using System.Windows;
using System.Windows.Media;

namespace WpfApplication1
{
public partial class Window2 : Window
{
private static SolidColorBrush CurrentBrush =
new SolidColorBrush(Colors.White);

public Window2()
{
InitializeComponent();
}

private void button1_Click(object sender, RoutedEventArgs e)
{
if (textBox1.Text.Length == 8)
{
string t = textBox1.Text;
byte value = 0;
byte[] argb = {0,0,0,0};
System.Globalization.NumberStyles nshex =
System.Globalization.NumberStyles.HexNumber;
bool failed = false;
for (int i=0; i<4; i++)
{
if (byte.TryParse(t.Substring(i * 2, 2), nshex,
null, out value))
{
argb = value;
}
else
{
failed = true;
break;
}
}
if (!failed)
{
CurrentBrush.Color =
Color.FromArgb(argb[0], argb[1], argb[2], argb[3]);

this.Resources["ColorDyn"] = CurrentBrush;
return;
}
}
this.TbHint.Visibility = Visibility.Visible;
this.Resources["ColorDyn"] = Brushes.White;

}
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top