Mazze

Hi!

I'm having troubles setting up a data binding in WPF. I would like to bind the DockPanel's "ActualWidth" property to the "Width" property of a self-coded class called XAxis:

// XAxis class exposes Width property of type double for binding purposes

class XAxis

{

public double Width

{

get { return width; }

set

{

if (value != width)

{

width = value;

UpdateScale();

}

}

}

}

// Instantiate XAxis and DockPanel and set up binding

DockPanel xAxisPanel = new DockPanel();

XAxis xAxis = new XAxis();

Binding xAxisWidthBinding = new Binding("Width");

xAxisWidthBinding.Source = xAxis;

xAxisWidthBinding.Mode = BindingMode.OneWayToSource;

xAxisPanel.SetBinding(DockPanel.ActualWidthProperty, xAxisWidthBinding);

However, when debugging the code I always get the following error message:

'ActualWidth' property cannot be data-bound.
Parameter name: dp

Anyone got an idea as to how to solve this issue

Thanks for helping out!

Best regards

Mazze



Re: Windows Presentation Foundation (WPF) Binding to a non-dependency property

Adam Smith - MSFT

ActualWidth is a read-only property, that reflects the result of the most recent layout pass upon the size of the element. As such, it cannot be set, whether via binding or directly. Is there a reason binding to DockPanel.Width doesn't work for you




Re: Windows Presentation Foundation (WPF) Binding to a non-dependency property

Alan Cobb

Hi Mazze,

It looks like you really want the DockPanel . ActualWidthProperty to be the binding source property and xAxis.Width to be the target property. I assume you're using the OneWayToSource binding mode because xAxis.Width is not a DependencyProperty (DP) and hence can't be a binding target property. So you figured you'd use OneWayToSource to work around that problem.

As Adam points out, WPF won't allow a ReadOnly DP to be used as a data-binding target property, period. (Although it is OK as a binding source property). You might reasonably think that a ReadOnly DP would work if the mode was OneWayToSource since the binding system would just be reading the target property not trying to write it. But the current version of WPF doesn't seem to allow for the relatively rare OneWayToSource special case. If you use Reflector on the method that is throwing the original inner exception you can see the tests the current WPF makes when deciding to throw the exception.

As Adam suggests, if you replace the target property DockPanel . ActualWidthProperty (ReadOnly) with DockPanel . WidthProperty (NOT ReadOnly) then you won't get the exception.

But again, what you probably want is the source property to be DockPanel . ActualWidthProperty and the target property to be xAxis . Width. You could do that by making xAxis . Width a custom DP (and obviously not ReadOnly). It's actually not that hard to create a custom DP. The following code adds a simple DP called DPBackedWidth to your XAxis class. In my test project I reconfigured your code to make XAxis . DPBackedWidthProperty the target property and it worked OK (assuming that's what you want). You would also need to change your XAxis class to derive from DependencyObject so that it can host a DP and also change to setting the binding using the static method BindingOperations . SetBinding(...).

-------------------------- code below -----------------------
// Define DependencyProperty.
public static DependencyProperty DPBackedWidthProperty;

// Expose DependencyProperty as CLR property.
public double DPBackedWidth
{ set
{ SetValue(DPBackedWidthProperty, value);
}
get
{ return (double)GetValue(
DPBackedWidthProperty
);
}
}

// Create DependencyProperty in static constructor:
//
static XAxis()
{
DPBackedWidthProperty =
DependencyProperty.Register(
"DPBackedWidth",
typeof(double),
typeof(XAxis),
new FrameworkPropertyMetadata(
0.0
)
);
}
-------------------------------------------------

Alan Cobb






Re: Windows Presentation Foundation (WPF) Binding to a non-dependency property

Mazze

Alan,
Adam,

Thanks very much for taking care of my coding problem. I'm positively surprised you guys replied so quickly and detailed. I really appreciate that!

It's also good to see how to construct dependency properties, but frankly speaking making each property a dependency property is quite laborious. This holds especially true when comparing former binding practices in windows forms applications with WPF.

You are right in assuming that I set the binding mode to 'OneWayToSource' so that only the 'Width' property on the XAxis gets updated thus leaving the readonly property 'ActualWidth' unchanged. IMHO it's quite reasonable to assume that a set up like this should work. Perhaps I'm the only one with this opinion, but if I'm not this might be something to take into account for future WPF releases.

Of course, rather than binding properties to each other, I could also subscribe to events to set the values within the handler. But I'm not sure whether this would adhere to best practice. I'm not an expert, so I don't know what's going on behind the code. I would guess that a synchronized value only holds a reference to its source thus eating up less memory than a non-synchronized value. Am I right in assuming that binding saves resources in contrast to event handling

Once again, thanks for your help!


Kind regards
Mazze




Re: Windows Presentation Foundation (WPF) Binding to a non-dependency property

Alan Cobb

Hi Mazze,

As you probably know, dependency properties (DPs) are used all over the place in WPF. Most of the interesting features of WPF are built on top of its "DP system": Data binding, animation, styles, templates, etc.. Most DPs in WPF are read-write and hence can be used as data-binding target properties. You just ran into one that is read-only, so it requires more work than usual.

Using either data-binding or a custom event handler would be OK in this case although WPF best-practices would lean toward data-binding, IMO. DPs are stored in a slightly more efficient way than regular properties, but unless you were adding a huge number of them it wouldn't be a big consideration.

Regarding getting used to writing your own DPs, I like this quote from Charles Petzold: http://www.charlespetzold.com/blog/2007/05/121019.html

"Dependency properties are so integral to the workings of WPF and XAML that nary a day goes by when I don't define one, even when the property will potentially serve only as a binding source rather than a target. Although it took me awhile to get accustomed to it, I like the structure that dependency properties imposes on my WPF classes."

Alan Cobb