WPF MVVM通过DependencyProperty获取UserControl实际位置

时间:2015-08-20 20:00:23

标签: wpf mvvm

我有一个非常常见的设计MVVM应用程序:MainWindow有一个ContentPresenter定义如下:

    <ContentPresenter Grid.Row="1" Grid.Column="1"
                      Content="{Binding Path=CurrentViewModel}">
    </ContentPresenter>

它使用DataTemplate并可以切换视图:

    <DataTemplate DataType="{x:Type vm:PlateEntireViewModel}">
        <v:PlateEntireView/>
    </DataTemplate>

PlateEntireView是一个UserControl,其PlateEntireViewModel为DataContext。现在 - 我希望在PlateEntireViewModel中有一个属性,它将在MainWindow中保存PlateEntireView实际位置(Left,Top)。可以接受这个吗?是否可以制作一些DependencyProperty并在PlateEntireView中使用它,例如:

    <Grid ext:CustomProperties.ActualPositionX="{Binding Path=ActualPositionX, Mode=OneWayToSource}">
    </Grid>

有人可以告诉我它是否是正确的尝试方式 - 以及如何使用它?

1 个答案:

答案 0 :(得分:0)

因此,对此最短的答案通常是ViewModel不关心在View中显示的特定坐标。据说可以做到这一点相对简单。

您需要做的就是设置一个附加属性,该属性将从屏幕左上角检索点

public static double GetXCoordinate(DependencyObject obj)
    {
        var fe = obj as FrameworkElement;
        if (fe != null)
        {
            return (fe.PointToScreen(new Point())).X;
        }
        return -1;
    }

    public static void SetXCoordinate(DependencyObject obj, double value)
    {
        obj.SetValue(XCoordinateProperty, value);
    }

    // Using a DependencyProperty as the backing store for XCoordinate.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty XCoordinateProperty =
        DependencyProperty.RegisterAttached("XCoordinate", typeof(double), typeof(CustomProperties), new PropertyMetadata(0.0));

然后你就可以拥有这样的装订外观

<local:control Grid.Column="1"
                   Grid.Row="1" 
                   x:Name="cp"
                   local:CustomProperties.XCoordinate="{Binding XCoordinate, UpdateSourceTrigger=Explicit}"
                   />

您需要明确更新,因为此绑定永远不会触发任何更改事件。您可以通过在您的视图中挂钩合理的事件来做到这一点。有关该外观的更多信息here