我如何在代码中绑定到Canvas.Left或Canvas.Top附加属性?

4
我正在尝试创建一个可在 Canvas 内拖动的 UserControl。我刚接触 MVVM,对 WPF 相对较新(同时也是 StackOverflow 的新手)。
我有一个视图模型,实现了 INotifyPropertyChanged,用于新的 UserControl,其中有名为“Top”和“Left”的属性。我想将视图模型的 Top 和 Left 属性绑定到 UserControl 的附加属性 Canvas.LeftCanvas.Top。由于某些原因,我不能使用任何 XAML
这是我实现我的 Left(以及类似的 Top)属性的方式(还不确定如何使代码高亮工作):
public class FooViewModel : INotifyPropertyChanged
{
    // . . .
    double _left;
    public double Left 
    { 
        get { return _left; }
        set
        {
            if(_left != value)
            {
                _left = value;
                NotifyPropertyChanged("Left");
            }
        }
    }
    // . . .
}

这是我实现“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);

        // . . .
    }
    // . . .
}

为了测试,我手动创建了一些视图模型实例,并在它们上面设置了Left和Top属性,通过将这些实例传递给构造函数创建了我的UserControl的实例,并将它们添加到Canvas中。不幸的是,我添加的所有控件都显示在Canvas的左上角,而调试器显示虽然视图模型的Top和Left属性已正确设置,但在控件上调用Canvas.GetLeft(...)和Canvas.GetTop(...)返回NaN。
我做错了什么?我采取了错误的方法吗?
我尝试基于这个问题和答案编写代码。
编辑: 实际上,这个方法是可行的!我的代码中有一个错误,即UserControl没有正确引用视图模型的实例。一旦我正确地连接了它,它就正常工作了。谢谢大家!

我试图基于这个问题的答案来解决我的问题,我认为它基本上实现了我在XAML中想要的。他们提到TwoWay模式允许数据源(我的视图模型)在用户在画布中移动控件时得到更新(最终我打算让它们可拖动)。 - axanpi
@Pysul:这取决于拖动的实现方式,如果是这种情况,我也会编辑VM而不是画布属性。 - H.B.
1
你能提供将控件添加到画布的代码吗?我刚刚使用你的代码快速制作了一个示例,它可以正常工作,所以我相信问题出在其他地方,在你上面没有提供的代码中。 - Tyson
明天我回到电脑前会尽量发布更完整的代码。 - axanpi
1个回答

3

那段代码应该可以很好地运行。

这些控件是否实际上是画布的直接子元素?如果不是,它将无法正常工作。


你是对的,它确实可以工作!今天早上重新审视调试器时,我注意到由于构造函数中的拼写错误,用户控件没有正确地连接到视图模型(糟糕!)。感谢大家的帮助 - 你们确认代码应该可以工作,让我保持在正确的轨道上,而不是试图解决不存在的问题。 - axanpi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接