PGP-Protector

Binding and DependencyProperty

by on Apr.11, 2013, under Coding

Long story short.
I was trying to create a custom object that I can bind to, not bind from.

So off to google dealing with WPF, Binding, UserControls, ect….

Lots of results on how to bind a variable to a text box, data table , list to drop boxes and all that, but What I was wanting to do was a bit different.

I wanted to use my own control that draws a “Target” on a canvas map, and allows you to Move the Target just by updating the Location(a System.Windows.Point) should be simple right?
Well it is after you figure out what you’re doing 🙂

My Thread that generates the X,Y coordinates for a Robot Map was running find, and the X & Y Values were bound to a text box on the main form, so I know it’s running fine in the background.
Any time it changes the X Or Y Value, it would also update the Location Point, and send a NotifyPropertyChanged(“CurrentLocation”); to boot.  That was working fine also.

But how to get my control to receive it?????

There were two problems.
1) it wasn’t a single variable I’m trying to get, but a Point object
2) how to allow it to Receive the Binding, not Set a binding.

So I give you the solution that I found, (And it works for me) though I’m sure it needs improvements.

 

using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;

namespace MyApplication
{
  public class TargetCurser : UserControl
  {
    public static readonly DependencyProperty TargetProperty = DependencyProperty.Register("MyPoint", typeof(Point), typeof(TargetCurser),new PropertyMetadata(new Point(0,0),OnTargetPropertyChanged));
    private Point _MyPoint = new Point(0, 0);
    public Point MyPoint { get { return _MyPoint; } set { _MyPoint = value; MoveTo(MyPoint); } }
    private static void OnTargetPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
      {
        TargetCurser control = sender as TargetCurser;
        if (control != null) { control.MyPoint = (Point)e.NewValue;}
      }
    private Path TargetObject = null;
    private Canvas TargetsCanvas = null;
    private Path TObject(string ObjectName, double Size, Color TargetColor)
    {
       // Snip COde, just build a Path of what you want and store it in LinePath to return.
       return LinePath;
    }
    private void MoveTo(Point NewLocation)
      {
      if (TargetsCanvas == null) return; // Can't move if we're not given a valid surface to move on.
      if (TargetObject == null) return; // Can't Move if we haven't build the TargetObject
      Path FindTargetOnCanvas = TargetsCanvas.FindName(TargetObject.Name) as Path;
      if (FindTargetOnCanvas == null) return; // Unable to Find Target on Path, can't move it.
      FindTargetOnCanvas.SetValue(Canvas.TopProperty, NewLocation.Y * ScalingFactor);
      FindTargetOnCanvas.SetValue(Canvas.LeftProperty, NewLocation.X * ScalingFactor);
      }
    public TargetCurser(Canvas DrawOn, string TargetsName)
      {
      UIElement ExistCheck = DrawOn.FindName(TargetsName) as UIElement;
      if (ExistCheck != null)
      {
        DrawOn.UnregisterName(TargetsName);
        DrawOn.Children.Remove(ExistCheck);
      }

      TargetObject = TObject(TargetsName, 5, Colors.Red);
      TargetsCanvas = DrawOn;
      TargetsCanvas.RegisterName(TargetObject.Name, TargetObject);
      TargetsCanvas.Children.Add(TargetObject);
      MoveTo(MyPoint);
      }
    }
}

Now for a bit of explaining.

1) You don’t need the INotifyPropertyChanged bit of code for a control that will be RECEIVING the Binding unless you’re also changing values and wish to send it back out.
2) public static readonly DependencyProperty TargetProperty = DependencyProperty.Register(“MyPoint”, typeof(Point), typeof(TargetCurser),new PropertyMetadata(new Point(0,0),OnTargetPropertyChanged));
This is where I was having the trouble, It would “Bind” tell I modified the last part PropertyMetadata(Default Value, WhatToDo)
Given my object is expecting a Point, I used new Point(0,0) vs a Null or 0 or “” like in some of the examples I saw on the net.
and the WhatToDo / OnTargetPropertyChanged (What ever void Property you’re wanting called when the variable bound to this changes);
3) private static void WhatToDo(DependencyObject sender, DependencyPropertyChangedEventArgs e)
This is where you’ll process any data that is Sent to your object / class when the Data Bound to your class changes, the new & old value will be in “e” (PropertyChangedEventArgs.


Leave a Reply

You must be logged in to post a comment.

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!