0

我在用户控件 (InfoControl) 中有 2 个文本框,绑定到实现 INotifyPropertyChanged 的​​ VM 中的 Point 属性。

我有另一个包含可拖动矩形的 UserControl (DesignerControl)。Rectangle 的 Canvas.Left 和 Canvas.Bottom 绑定到同一 VM 的 ConvPoint 属性。ConvPoint 属性 (0 => ActualWidth) 是 Point 属性 (0 => 1) 的转换版本

当我拖动我的矩形时,ConvPoint VM 属性和文本框中的值会立即更新,但是当我用新值更新我的文本框时,VM Point 属性会立即更新,但只有当我再次拖动矩形时才会定位矩形并且不是立即。

一点代码解释一下:

一、我的ViewModel的Position属性

public class MyVM : ViewModelBase
{
    private DependencyPoint position;
    public DependencyPoint Position
    {
        get { return this.position; }
        set
        {
            this.position = value;
            RaisePropertyChanged("Position");
        }
    }

    public DependencyPoint ConvPosition
    {
        get { return new Point(this.Position.X * MainVM.ActualWidth, this.Position.Y * MainVM.AcutalHeight);}
        set
        {
            Point p = new Point(value.X/MainVM.ActualWidth,value.Y/MainVM.ActualHeight);
            this.position = p;
            RaisePropertyChanged("ConvPosition");
        }
    }
}


编辑: 我为此使用一个类 DependencyPoint 来通知 X 和 Y 属性:

public class DependencyPoint : DependencyObject
{

    public enum PointOrder
    {
        isStartPoint,
        isEndPoint,
        isPoint1,
        isPoint2
    }

    public DependencyPoint()
    {
    }

    public DependencyPoint(Double x, Double y, PointOrder po)
    {
        this.X = x;
        this.Y = y;
        this.Order = po;
    }

    public DependencyPoint(DependencyPoint point)
    {
        this.X = point.X;
        this.Y = point.Y;
        this.Order = point.Order;
    }


    public DependencyPoint(Point point, PointOrder po)
    {
        this.X = point.X;
        this.Y = point.Y;
        this.Order = po;
    }

    public Point ToPoint()
    {
        return new Point(this.X, this.Y);
    }



    public PointOrder Order
    {
        get { return (PointOrder)GetValue(OrderProperty); }
        set { SetValue(OrderProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Order.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty OrderProperty =
        DependencyProperty.Register("Order", typeof(PointOrder), typeof(DependencyPoint), new UIPropertyMetadata(null));



    public Double X
    {
        get { return (Double)GetValue(XProperty); }
        set { SetValue(XProperty, value); }
    }

    // Using a DependencyProperty as the backing store for X.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty XProperty =
        DependencyProperty.Register("X", typeof(Double), typeof(DependencyPoint), new UIPropertyMetadata((double)0.0));



    public Double Y
    {
        get { return (Double)GetValue(YProperty); }
        set { SetValue(YProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Y.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty YProperty =
        DependencyProperty.Register("Y", typeof(Double), typeof(DependencyPoint), new UIPropertyMetadata((double)0.0));
}


然后在我的信息控制中:

<Grid Grid.Row="0" DataContext="{Binding Position}">
                <Grid.RowDefinitions>
                    <RowDefinition/>
                    <RowDefinition/>
                </Grid.RowDefinitions>
                <DockPanel Margin="3,3,0,1" Grid.Row="0" LastChildFill="True">
                    <TextBlock Foreground="White" Padding="0,3,0,0" Margin="2,0,0,0" DockPanel.Dock="Left" Text="StartPoint.X :"/>
                    <TextBox FontWeight="DemiBold" Foreground="Black" Background="#efefef" Width="Auto" Margin="7,0,0,0" Text="{Binding X, Converter={StaticResource StDConverter}, UpdateSourceTrigger=LostFocus, Mode=TwoWay}"/>
                </DockPanel>
                <DockPanel Margin="3,3,0,1" Grid.Row="1" LastChildFill="True">
                    <TextBlock Foreground="White" Padding="0,3,0,0" Margin="2,0,0,0" DockPanel.Dock="Left" Text="StartPoint.Y :"/>
                    <TextBox FontWeight="DemiBold" Foreground="Black" Background="#efefef" Width="Auto" Margin="7,0,0,0" Text="{Binding Y, Converter={StaticResource StDConverter}, UpdateSourceTrigger=LostFocus, Mode=TwoWay}"/>
                </DockPanel>
            </Grid>

在 DesignerControl 中:

<UserControl>
    <Canvas>
        <Rectangle x:Name="Point" Width="10" Height="10" Canvas.Bottom="{Binding ConvPosition.Y, Mode=TwoWay}" Canvas.Left="{Binding ConvPosition.X, Mode=TwoWay}" />
    </Canvas>
</UserControl>

我可以访问 actualWidth 并且我的 Rectangle 位于 Canvas 中。

我知道我在虚拟机中的属性或有点脏,但我不知道另一种方法可以正确地完成它并管理转换。

有任何想法吗?

4

1 回答 1

0

因为 ConvPosition 取决于 Position,所以您应该在 Position 设置器中为 ConvPosition 提出 NotificationChanged。

public Point Position
{
    get { return this.position; }
    set
    {
        this.position = value;
        RaisePropertyChanged("Position");
        RaisePropertyChanged("ConvPosition");
    }
}

ConvPosition 你可以改成这个

public Point ConvPosition
{
    get { return new Point(this.Position.X * MainVM.ActualWidth, this.Position.Y * MainVM.AcutalHeight); }
    set
    {
        this.Position = new Point(value.X/MainVM.ActualWidth, value.Y/MainVM.ActualHeight);
    }
}

编辑

我认为 MyVM 中的两个附加属性将是最简单的解决方案。

public double X
{
    get { return Position.X; }
    set
    {
        Position = new Point(value, Position.Y);
        RaisePropertyChanged("X");
    }
}

public double Y
{
    get { return Position.Y; }
    set
    {
        Position = new Point(Position.X, value);
        RaisePropertyChanged("Y");
    }
}

仅在网格中更改:

<Grid DataContext="{Binding}">
于 2012-07-03T21:38:40.497 回答