I am trying to create a UserControl that is draggable in a Canvas. I am brand new to MVVM and relatively new to WPF (also pretty new to StackOverflow).
I have a view model, which implements INotifyPropertyChanged, for the new UserControl that has properties called “Top” and “Left”. I would like to bind the Top and Left properties of my view model to the attached Canvas.Left and Canvas.Top of the UserControl. For reasons I won’t get into, I can’t use any XAML.
This is how I’ve implemented my Left (and similarly Top) properties (not sure how to make code highlighting work yet):
public class FooViewModel : INotifyPropertyChanged
{
// . . .
double _left;
public double Left
{
get { return _left; }
set
{
if(_left != value)
{
_left = value;
NotifyPropertyChanged("Left");
}
}
}
// . . .
}
This is how I’ve implemented my ‘UserControl’:
public class FooControl : UserControl
{
// . . .
private FooViewModel _vm;
public FooControl(FooViewModel vm)
{
_vm = vm;
this.DataContext = _vm;
Binding b = new Binding("Left");
b.Mode = BindingMode.TwoWay;
this.SetBinding(Canvas.LeftProperty, b);
// . . .
}
// . . .
}
To test, I have manually created some view model instances, set the Left and Top properties on them, created instances of my UserControl by passing these to the constructor, and added them to a ‘Canvas’. Unfortunately, all of my added controls show up in the top-left corner of the ‘Canvas’ and the debugger shows that while the Top and Left properties of the view model are set correctly, calling Canvas.GetLeft(...) and Canvas.GetTop(...) on the controls return NaN.
What am I doing wrong? Am I taking the wrong approach?
I’ve tried to base my code around this question & answer.
EDIT:
Actually, this does work! I had mistake in my code where the UserControl wasn’t getting a proper reference to an instance of the view model. Once I hooked that up correctly it worked fine. Thanks everyone!
That code should work just fine.
Are the controls actually immediate children of the canvas? If not it will not work.