jfhspike

Suppose I want to make a class, Blob. It has a location, and I'd like that to be a DependencyProperty. I think "Let's make Location a Point". So I write some code like

Code Block

public static readonly DependencyProperty PositionProperty =

DependencyProperty.Register("Position",

typeof(Point), typeof(Blob),

new FrameworkPropertyMetadata(initialPosition,

FrameworkPropertyMetadataOptions.AffectsMeasure,

new PropertyChangedCallback(PositionValueChanged), null));

///

/// Gets or sets the Position of the Blob

///

public Point Position

{

set { SetValue(PositionProperty, value);}

get { return (Point)GetValue(PositionProperty); }

}

...and the PositionValueChanged method as well, etc. So far, so good.

Then I find that as I animate my Blobs, I'd really like to be able to change just the X or the Y coordinate of the position. So I say "I'll just add two new DependencyPropertys called "X" and "Y", sort of like the X1, Y1, X2, Y2 of a linesegment."

Then comes the clincher: when "Position" gets changed, I'd better update "X", with code that looks something like this:

Code Block

public Point Position

{

set {

SetValue(PositionProperty, value);

SetValue(X, value.X);

SetValue(Y, value.Y);

}

get { return (Point)GetValue(PositionProperty); }

}

where the highlighted lines are new.

But when "X" gets changed, I have to update "Position" as well. It's easy to believe that if I make each dependent on the other, I'll get an infinite back-and-forth of changes, none of which matter except the first.

So:

1: is the idea of redundant Dependency Properties frowned on

2: If not, what's the right way to avoid infinite back-and-forth in the property-setting code

Thanks in advance,

John



Re: Windows Presentation Foundation (WPF) Redundant Dependency Properties

TheCPUWizard-2007

Not sure if this applies 100% to your scenarion, but I (almost) always check the current value of a property (in any environment) before actually setting it. This will usually provide self stabilizing behavior...






Re: Windows Presentation Foundation (WPF) Redundant Dependency Properties

tasosval

I don't think you are on the right track mate.

First of all it is imperative that you don't do anything at the public property that exposes the DependencyProperty. This is because this property is rarely used by the inner workings of WPF, instead most commonly used are the GetValue and SetValue methods.

If you want to do something extra when changing the value of a property then you should register a Callback (as I see that you do in the code you provide) and do what you want in there. For example in your case I would do this:

Code Block

public static readonly DependencyProperty PositionProperty =
DependencyProperty.Register("Position",
typeof
(Point), typeof(Blob),
new
FrameworkPropertyMetadata(initialPosition,
FrameworkPropertyMetadataOptions
.AffectsMeasure,
new
PropertyChangedCallback(PositionValueChanged), null));


///
///
Gets or sets the Position of the Blob
///

public
Point Position
{
set
{ SetValue(PositionProperty, value);}
get
{ return (Point)GetValue(PositionProperty);

}



private static void PositionValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if ( d is YourClass ){
YourClass me = (YourClass )d;
if ( e.NewValue is Point ){
Point p = (Point) e.NewValue;
me.X = p.X;
me.Y = p.Y;
}
}
}




I hope this helps :-)




Re: Windows Presentation Foundation (WPF) Redundant Dependency Properties

Jordan Parker - MSFT

tasosval is correct in that the parser won't call your public property if it can access the DP directly.

Yes, we frown upon chaining DPs together because it can lead to really bizzare results and very hard to debug situations. One issue is a DP can get its value from many sources and there is a precedence order to them. Say you're animating the X DP which then updating Position. If you then go and manually change Position while the animation to X is still going on, I believe X will keep animating and have precedence over the value you just gave to Position. When X updates again, your local Position value will be overwritten.

The recommended way to chain DPs together is to use data binding. You could databind X and Y to Position.X and Position.Y but then you lose the ability to set X/Y because setting them would drop the data bind.

It depends on what your usage scenario is, but you could just make X and Y be the DPs and have Position not be but pull its values from X and Y.





Re: Windows Presentation Foundation (WPF) Redundant Dependency Properties

jfhspike

Thanks. I think that the "you shouldn't really do this" from Jordan is what I was looking for; it's true that this'll make for uglier code in some cases, but if it's easier to debug, then it's a win. I *could* move to "X and Y are DPs" as tasosval suggests, but that's actually the rarer-use case for me.

--John