wpf - databinding problem

R

Rolf Welskes

Hello,
because there are no news group for window presentation foundation and one
has told me I can use this, here my problem:

I make the following binding in code:



SolidColorBrush mySolidColorBrush = new
SolidColorBrush(Colors.Green);


Binding bdx01 = new Binding();
bdx01.Source = mySolidColorBrush;
BindingOperations.SetBinding(myTextBlock01,
TextBlock.BackgroundProperty, bdx01);

Binding bdx02 = new Binding();
bdx02.ElementName = "myPanel"; //myPanel
is the name of the Control I where I am here.
bdx02.Path = new PropertyPath("MyColor");

BindingOperations.SetBinding(mySolidColorBrush,
SolidColorBrush.ColorProperty, bdx02);


Remark: MyColor property is declared in this code before as
DependencyProperty.

So if I would change MyColor so mySolidColorBrush should change the color
and so myTextBlock-Background should change.

It s here to see that binding can be in a chain.

This sampel does not work.
BUT if I add the following line:
myTextBox.Background = mySolidColorBrush; //myTextBox is any
textbox

then all works fine.

We have: myTextBlock.Background is bind to mySolidColorBrush
and mySolidColorBrush is bind to MyColor

Why does this only work, if I add the line where an element get the brush
directly.

Thank you for any help.
Rolf Welskes
 
W

Walter Wang [MSFT]

Hi Rolf,

I'm sorry but I cannot fully understand your question and reproduce the
issue using your posted code. Could you please create a complete but small
reproducible project and send it to me? Thanks.


Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
R

Rolf Welskes

Hello,
thank you, here the informations:
(Remark what you think is a news group is a forum as I know, means you get
answers in weeks).

xaml:
<Window x:Class="Test01.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="328" Width="435"
Name="myWin">
<!-- IMPORTANT: Name must be declared -->

<Grid Background="LightGray">
<Rectangle Height="69" HorizontalAlignment="Left" Margin="33,24,0,0"
Name="rect01" Stroke="Black" VerticalAlignment="Top" Width="142" />
<TextBox Height="21" HorizontalAlignment="Left" Margin="236,30,0,0"
Name="txDummy" VerticalAlignment="Top" Width="120" />
</Grid>
</Window>

Code behind:

namespace Test01
{
public partial class Window1 : Window
{

SolidColorBrush br;
public static readonly DependencyProperty myColorProperty;

public Color MyColor
{
get{return (Color)GetValue(myColorProperty);}
set{SetValue(myColorProperty, value);}
}

static Window1()
{
myColorProperty = DependencyProperty.Register("MyColor",
typeof(Color), typeof(Window1));
}

public Window1()
{
InitializeComponent();

br = new SolidColorBrush(Colors.SaddleBrown);

MyColor = Colors.Red;

Binding bdx01 = new Binding();
bdx01.Source = br;
BindingOperations.SetBinding(rect01, Rectangle.FillProperty,
bdx01);

Binding bdx02 = new Binding();
bdx02.ElementName = "myWin";
bdx02.Path = new PropertyPath("MyColor");

BindingOperations.SetBinding(br, SolidColorBrush.ColorProperty,
bdx02);

//txDummy.Background = br;
}
}

So, because I set MyColor = Colors.Red, the rectangle should be red. - but
is not.
When I un-comment txDummy.Background = br,
Rectangle is red.

Thank you for any help and best regards
Rolf Welskes

}
 
W

Walter Wang [MSFT]

Hi Rolf,

Now I understand that your purpose is to use an SolidColorBrush to use the
MyColor property in Rectangle.Fill. Your code doesn't work because the
SolidColorBrush doesn't implement INotifyPropertyChanged and will not
automatically propagate the change when the MyColor property is changed.

The correct approach is to create a Converter for the Color ->
SolidColorBrush and assign this converter to the Binding:

[ValueConversion(typeof(Color), typeof(SolidColorBrush))]
public class ColorBrushConverter : IValueConverter
{
public object Convert(object value, Type targetType, object
parameter, System.Globalization.CultureInfo culture)
{
Color color = (Color)value;
return new SolidColorBrush(color);
}

public object ConvertBack(object value, Type targetType, object
parameter, System.Globalization.CultureInfo culture)
{
return null;
}
}


Binding b = new Binding("MyColor");
b.Source = myWin;
b.Converter = new ColorBrushConverter();
BindingOperations.SetBinding(rect01, Rectangle.FillProperty, b);


This is described in following MSDN library page:

#Data Binding Overview
http://msdn2.microsoft.com/en-us/library/ms752347.aspx#data_conversion
<quote>
However, what if instead of having a property of type string your binding
source object has a Color property of type Color? In that case, in order
for the binding to work you would need to first turn the Color property
value into something that the Background property accepts. You would need
to create a custom converter by implementing the IValueConverter interface,
</quote>


Hope this helps.


Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
R

Rolf Welskes

Hello,
thank you,
but what you make is a work around of the problem.
This is not my problem.
The problem is: The Color of the Brush must be changed
and this change must be visible in the rectangle where the brush is the
background.
It is the chaining of the binding what is the problem, because this is only
a test for the chaining.
I bind rect-background to brush then I bind Color of the brush to
MyColor-Property.
this is the chain of binding.
Now the MyColor-Property changes the color,
now the brush has an other color and the rectangle must have the new color
of the brush.

The workaround is not usable in other scenarios.

Thank you and best regards
Rolf Welskes
 
W

Walter Wang [MSFT]

Hi Rolf,

Thanks for your reply.

Your code was directly binding to the SolidColorBrush, however, it doesn't
implement INotifyPropertyChanged. As a result, it will not notify you when
its property is changed.

Actually you should create a public property to return the Window's
SolidColorBrush and you can bind to the window and use the property path:

SolidColorBrush br;

public SolidColorBrush MyBrush
{
get { return br; }
set { br = value; }
}


public Window1()
{
InitializeComponent();

br = new SolidColorBrush(Colors.SaddleBrown);

MyColor = Colors.Red;

Binding bdx01 = new Binding();
bdx01.Source = this;
bdx01.Path = new PropertyPath("MyBrush");
BindingOperations.SetBinding(rect01, Rectangle.FillProperty,
bdx01);

Binding bdx02 = new Binding();
bdx02.Source = this;
bdx02.Path = new PropertyPath("MyColor");
BindingOperations.SetBinding(br,
SolidColorBrush.ColorProperty,bdx02);

//txDummy.Background = br;
}



Hope this helps.


Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
R

Rolf Welskes

Hello,
thank you for your answer.
BUT - I do not belive this.
Brush is a Freezable - and if Color changes as sub-property - Brush should
inform the target where it is bound.

But you have made another change and this shows where the proble is.

In the original code I sent to you
replace:

bdx02.ElementName = "myWin";
to
bdx02.Source = this´;

now it works.

So, seems using Binding.ElementName in code is a problem,
I have tried it in xaml - no problem.

Binding.ElementName should give the same object
as setting Binding.Source - but seems it does not.
WHY?

Thank you for your help and best regards
Rolf Welskes
 
W

Walter Wang [MSFT]

Hi Rolf,

It turns out a known issue of WPF, we have an open bug for it. The root
cause here is that setting binding source via ElementName in code doesn't
set the SolidColorBrush's inheritance context.

#Nick on Silverlight and WPF : What's an inheritance context?
http://blogs.msdn.com/nickkramer/archive/2006/08/18/705116.aspx

If we assign the SolidColorBrush to the dummy TextBlock.Background, since
the TextBlock is also in the logical tree, the brush now gets correct
inheritance context.

We're sorry for the inconvenience caused. Please feel free to let me know
if there's anything else I can help.


Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
R

Rolf Welskes

Hello,
thank you,
so the problem in this sence is solved.
Thank you again and best regards
Rolf Welskes
 

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