469,312 Members | 2,440 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,312 developers. It's quick & easy.

WPF: Trouble databinding to custom Dependency Property

I have a windows WPF sample project which is starting to work pretty good.
I can drag shapes and lines, and connect a straight line to any place on a
custom rectangle shape's boarder. Now I have a custom Polyline object which
I had to create some DPs to use in a MultiBinding. However, since I'm not
strong in using custom DPs yet, I'm getting an error when binding to the
custom DP.

When you run this project:

1) Drag the right end of the Red line (this is the Line) to the rectangle
and drop it. now drag the rectangle. You can see it stays connected.

2) Now drag the right end of the Blue line (this is the Polyline) and drop
it on the rectangle. You will get the error.

3) Note, you can right click on the ends of the Polyline to add additional
line segments. its pretty cool.

Can someone please show me how to create and bind thes custom DPs?

Thanks.

Note: the attachment was 107K so I could not post it. please send me an
email go g e o r g e p At n w i s Dot n e t.
and I will email it to you.
--
mo*******@noemail.noemail

Jan 23 '07 #1
3 9299
Hi moondaddy,

To simply the scenario, I will use your previous version of code (v3) to
demonstrate the idea on how to bind a Polyline's last point to a
Rectangle's border.

First, we can create following static class to add two DPs to the Polyline
and handle the callback when the value gets changed (i.e. the data binding
returns updated data):

public static class PolylineDPs
{
public static readonly DependencyProperty EndPointXProperty =
DependencyProperty.Register("EndPointX", typeof(double), typeof(Polyline),
new FrameworkPropertyMetadata(new
PropertyChangedCallback(EndPointX_Changed)));
public static readonly DependencyProperty EndPointYProperty =
DependencyProperty.Register("EndPointY", typeof(double), typeof(Polyline),
new FrameworkPropertyMetadata(new
PropertyChangedCallback(EndPointY_Changed)));

private static void EndPointX_Changed(DependencyObject sender,
DependencyPropertyChangedEventArgs e)
{
Polyline pl = (Polyline)sender;
Point p = pl.Points[pl.Points.Count - 1];
p.X = (double) (e.NewValue);
pl.Points[pl.Points.Count - 1] = p;
}

private static void EndPointY_Changed(DependencyObject sender,
DependencyPropertyChangedEventArgs e)
{
Polyline pl = (Polyline)sender;
Point p = pl.Points[pl.Points.Count - 1];
p.Y = (double)(e.NewValue);
pl.Points[pl.Points.Count - 1] = p;
}
}

After that, you can freely use the same LineBindingConverter and
MultiBinding object to bind the Polyline's end point to the Rectangle's
border:

Polyline DrawPolyline()
{
Polyline pl = new Polyline();
pl.Stroke = Brushes.Blue;
pl.StrokeThickness = 3;
pl.Points.Add(new Point(10, 10));
pl.Points.Add(new Point(50, 10));
pl.Points.Add(new Point(150, 150));
dragCanvas.Children.Add(pl);
return pl;
}

Line myLine = DrawLine();
SimpleRectangle myRect = DrawRectangle();
Polyline pl = DrawPolyline();

MultiBinding multiBinding = new MultiBinding();
multiBinding.Converter = new LineBindingConverter();
multiBinding.ConverterParameter = 1.0;

Binding binding = new Binding();
binding.Source = myRect;
binding.Path = new PropertyPath("Left");
multiBinding.Bindings.Add(binding);

binding = new Binding();
binding.Source = myRect;
binding.Path = new PropertyPath("Width");
multiBinding.Bindings.Add(binding);

myLine.SetBinding(Line.X2Property, multiBinding);
pl.SetBinding(PolylineDPs.EndPointXProperty, multiBinding);

multiBinding = new MultiBinding();
multiBinding.Converter = new LineBindingConverter();
multiBinding.ConverterParameter = 0.3;

binding = new Binding();
binding.Source = myRect;
binding.Path = new PropertyPath("Top");
multiBinding.Bindings.Add(binding);

binding = new Binding();
binding.Source = myRect;
binding.Path = new PropertyPath("Height");
multiBinding.Bindings.Add(binding);

myLine.SetBinding(Line.Y2Property, multiBinding);
pl.SetBinding(PolylineDPs.EndPointYProperty, multiBinding);
This will both bind the Line's end point and the Polyline's end point to
the same point on the right border of the Rectangle.

Hope this helps.

Regards,
Walter Wang (wa****@online.microsoft.com, 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.

Jan 24 '07 #2
Thanks Walter! As always, your samples and explanations are extremely
helpful. This is starting to work quite nicely.

Now, I need to know how to remove these bindings.

For example, here's my steps:

1) I drag the end of the polyline over the rectangle and on the
dragcompleted even I execute the code from the previous post which binds the
end of the polyline to the rectangle. Good.
2) Now I drag the end of the line off and away from the rectangle so I need
to Un-Bind the line from the rectangle.
3) Then, when I drag the rectangle, the 'EndPointY_Changed' event fires and
the end of the polyline jumps back to where its connected to the rectangle.

private static void EndPointY_Changed(DependencyObject sender,
DependencyPropertyChangedEventArgs e)
{
Polyline pl = (Polyline)sender;
Point p = pl.Points[pl.Points.Count - 1];
p.Y = (double)(e.NewValue);
pl.Points[pl.Points.Count - 1] = p;
}
}
I tried making the variables private at the class level so I could set them
to null after dragging the line away from the rectangle:

MultiBinding multiBinding;
Binding binding;

but that had no effect.

How do you recommend Un-Binding the line from the rectangle?

Thanks.

"Walter Wang [MSFT]" <wa****@online.microsoft.comwrote in message
news:rv**************@TK2MSFTNGHUB02.phx.gbl...
Hi moondaddy,

To simply the scenario, I will use your previous version of code (v3) to
demonstrate the idea on how to bind a Polyline's last point to a
Rectangle's border.

First, we can create following static class to add two DPs to the Polyline
and handle the callback when the value gets changed (i.e. the data binding
returns updated data):

public static class PolylineDPs
{
public static readonly DependencyProperty EndPointXProperty =
DependencyProperty.Register("EndPointX", typeof(double), typeof(Polyline),
new FrameworkPropertyMetadata(new
PropertyChangedCallback(EndPointX_Changed)));
public static readonly DependencyProperty EndPointYProperty =
DependencyProperty.Register("EndPointY", typeof(double), typeof(Polyline),
new FrameworkPropertyMetadata(new
PropertyChangedCallback(EndPointY_Changed)));

private static void EndPointX_Changed(DependencyObject sender,
DependencyPropertyChangedEventArgs e)
{
Polyline pl = (Polyline)sender;
Point p = pl.Points[pl.Points.Count - 1];
p.X = (double) (e.NewValue);
pl.Points[pl.Points.Count - 1] = p;
}

private static void EndPointY_Changed(DependencyObject sender,
DependencyPropertyChangedEventArgs e)
{
Polyline pl = (Polyline)sender;
Point p = pl.Points[pl.Points.Count - 1];
p.Y = (double)(e.NewValue);
pl.Points[pl.Points.Count - 1] = p;
}
}

After that, you can freely use the same LineBindingConverter and
MultiBinding object to bind the Polyline's end point to the Rectangle's
border:

Polyline DrawPolyline()
{
Polyline pl = new Polyline();
pl.Stroke = Brushes.Blue;
pl.StrokeThickness = 3;
pl.Points.Add(new Point(10, 10));
pl.Points.Add(new Point(50, 10));
pl.Points.Add(new Point(150, 150));
dragCanvas.Children.Add(pl);
return pl;
}

Line myLine = DrawLine();
SimpleRectangle myRect = DrawRectangle();
Polyline pl = DrawPolyline();

MultiBinding multiBinding = new MultiBinding();
multiBinding.Converter = new LineBindingConverter();
multiBinding.ConverterParameter = 1.0;

Binding binding = new Binding();
binding.Source = myRect;
binding.Path = new PropertyPath("Left");
multiBinding.Bindings.Add(binding);

binding = new Binding();
binding.Source = myRect;
binding.Path = new PropertyPath("Width");
multiBinding.Bindings.Add(binding);

myLine.SetBinding(Line.X2Property, multiBinding);
pl.SetBinding(PolylineDPs.EndPointXProperty, multiBinding);

multiBinding = new MultiBinding();
multiBinding.Converter = new LineBindingConverter();
multiBinding.ConverterParameter = 0.3;

binding = new Binding();
binding.Source = myRect;
binding.Path = new PropertyPath("Top");
multiBinding.Bindings.Add(binding);

binding = new Binding();
binding.Source = myRect;
binding.Path = new PropertyPath("Height");
multiBinding.Bindings.Add(binding);

myLine.SetBinding(Line.Y2Property, multiBinding);
pl.SetBinding(PolylineDPs.EndPointYProperty, multiBinding);
This will both bind the Line's end point and the Polyline's end point to
the same point on the right border of the Rectangle.

Hope this helps.

Regards,
Walter Wang (wa****@online.microsoft.com, 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.

Jan 24 '07 #3
You could use BindingOperations.ClearAllBindings() or ClearBinding to clear
the binding(s):

#BindingOperations.ClearAllBindings Method (System.Windows.Data)
http://msdn2.microsoft.com/en-gb/lib...indingoperatio
ns.clearallbindings.aspx

Please note: Clearing the binding removes the binding so that the value of
the dependency property is changed to whatever it would have been without
the binding. This value could be a default value, an inherited value, or a
value from a data template binding.
Regards,
Walter Wang (wa****@online.microsoft.com, 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.

Jan 25 '07 #4

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

8 posts views Thread by GaryDean | last post: by
3 posts views Thread by Peter | last post: by
3 posts views Thread by =?Utf-8?B?V29ua28gdGhlIFNhbmU=?= | last post: by
23 posts views Thread by raylopez99 | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by zhoujie | last post: by
reply views Thread by harlem98 | last post: by
reply views Thread by harlem98 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.