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



我有一个很常见的设计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, platewholviewmodel作为DataContext。现在-我想有一个属性在platewholviewmodel,这将保持PlateEntireView的实际位置(左,上)在主窗口内。这能实现吗?是否可以制作一些DependencyProperty并在PlateEntireView中使用它,如:

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

谁能告诉我这是正确的尝试方式-以及如何使用它?

所以这个问题的最简短的答案通常是ViewModel不会关心视图中显示的特定坐标。也就是说,相对简单地做到这一点是可能的。

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

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}"
                   />

您需要显式地更新,因为此绑定永远不会触发任何更改事件。您可以通过在视图中关联一个合理的事件来实现这一点。更多信息请看这里

最新更新