将 XAML 元素公开到 ViewModel 到 运行 方法 Xamarin Forms

Expose XAML Element to ViewModel to run methods Xamarin Forms

我需要能够在我的 ViewModel 中的 XAML 元素上使用 运行 方法,我有 3 个文件 - DataPrepPage.cs、DataPrepPage.xaml 和 DataPrepViewModel.cs.

在我的 XAML(DataPrepPage.xaml) 页面中,我有这样的元素:

<esriUI:MapView x:Name="MapElement" 
                Map="{Binding Map}"/>

我在父网格元素上设置绑定上下文,如下所示:

<Grid.BindingContext>
     <local:DataPrepViewModel/>
</Grid.BindingContext>

当然,我可以在代码隐藏中访问我的 MapView 元素和方法,例如:

MapElement.GraphicsOverlays.Add(MyOverlay);

所以问题是我需要能够在 ViewModel 中执行此操作,但 x:Name 不会将其公开给我的 ViewModel。

目前我的 ViewModel 中有一个静态变量

public static MapView MapView;

然后我在页面代码隐藏的构造函数中将我的元素分配给它:

    public DataPrepPage ()
    {
        InitializeComponent ();
        DataPrepViewModel.MapView = MapElement;
    }

这允许我在我的 ViewModel 中执行此操作:

MapView.GraphicsOverlays.Add(MyOverlay);

所以问题是:

如何在不使用静态的情况下将元素公开给我的 ViewModel? || 我如何 运行 对 ViewModel 中的元素使用方法?

MVVM 背后的整个想法是您的视图和视图模型是解耦的。您在问如何将它们再次耦合在一起。简短回答:不要。

您可以在 XAML 中绑定 GraphicsOverlays:

        <esri:MapView x:Name="MapView1" Height="517" MapViewTapped="MapView1_MapViewTapped">

            <!-- Add a Map. -->
            <esri:Map x:Name="Map1">

                <!-- Add a backdrop ArcGISTiledMapServiceLayer. -->
                <esri:ArcGISTiledMapServiceLayer ID="myArcGISTiledMapServiceLayer" 
                  ServiceUri="http://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer" />

            </esri:Map>

            <!-- Add a MapView.GraphicsOverlays collection. -->
        <esri:MapView.GraphicsOverlays>

            <!-- Add a GraphicsOverlay to hold Graphics added via code behind from a FindTask operation. Set the Renderer to draw the polygon graphics. -->
            <esri:GraphicsOverlay Renderer="{StaticResource mySimpleRenderer}"/>

        </esri:MapView.GraphicsOverlays>

    </esri:MapView>

更完整的文档是 here

因此,创建其他属性或 DependencyProperty 所需类型的实例,然后使用 XAML 绑定到这些新的视图模型属性。

为了完整起见,您可以像这样制作 XAML 元素 public:

<Button x:Name="MyButton" x:FieldModifier="public" />

但是您应该问问自己为什么要这样做,因为这可能是您应该避免的代码味道。