0

INotifyPropertyChanged を実装する VM のポイント プロパティにバインドされたユーザー コントロール (InfoControl) に 2 つの TextBox があります。

ドラッグ可能な四角形を含む別の UserControl (DesignerControl) があります。Rectangle には、同じ VM の ConvPoint プロパティにバインドされた Canvas.Left と Canvas.Bottom があります。ConvPoint プロパティ (0 => ActualWidth) は、Point プロパティ (0 => 1) の変換バージョンです。

四角形をドラッグすると、ConvPoint VM プロパティとテキスト ボックスの値が即座に更新されますが、テキスト ボックスを新しい値で更新すると、VM ポイント プロパティは即座に更新されますが、四角形を再度ドラッグしたときにのみ四角形が配置されます。即座にではありません。

説明するコードのビット:

まず、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));
}


次に、私のInfoControlで:

<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 に適切に配置されています。

VM のプロパティを知っているか、少し汚れていますが、それを適切に実行して変換を管理する他の方法も知りません。

何か案は?

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 に 2 つのプロパティを追加するのが最も簡単な解決策だと思います。

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 に答える