gpt4 book ai didi

c# - 使用 ArcGIS Runtime 本地服务器实现 MVVM

转载 作者:太空狗 更新时间:2023-10-29 21:37:28 25 4
gpt4 key购买 nike

我正在尝试设置一个 ESRI 本地服务器来显示 .mpk。我有一个像这样的模型

public class Model
{
private string basemapLayerUri = "http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer";
private string mapPackage = "D:\\App\\Data\\Canada.mpk";
public Model() { }

public string BasemapLayerUri
{
get { return this.basemapLayerUri; }
set
{
if (value != this.basemapLayerUri)
{
this.basemapLayerUri = value;
}
}
}

public string MapPackage
{
get { return this.mapPackage; }
set
{
if (value != this.mapPackage)
{
this.mapPackage = value;
}
}
}
}

ViewModel.cs 我有的类

public class ViewModel : INotifyPropertyChanged
{
public Model myModel { get; set; }

public event PropertyChangedEventHandler PropertyChanged;

public ViewModel()
{
myModel = new Model();
this.CreateLocalServiceAndDynamicLayer();
}

public string BasemapUri
{
get { return myModel.BasemapLayerUri; }
set
{
this.myModel.BasemapLayerUri = value;
OnPropertyChanged("BasemapUri");
}
}

public async void CreateLocalServiceAndDynamicLayer()
{
LocalMapService localMapService = new LocalMapService(this.MAPKMap);
await localMapService.StartAsync();

ArcGISDynamicMapServiceLayer arcGISDynamicMapServiceLayer = new ArcGISDynamicMapServiceLayer()
{
ID = "mpklayer",
ServiceUri = localMapService.UrlMapService,
};

//myModel.Map.Layers.Add(arcGISDynamicMapServiceLayer);
}

public string MAPKMap
{
get { return myModel.MapPackage; }
set
{
this.myModel.MapPackage = value;
OnPropertyChanged("MAPKMap");
}
}

protected void OnPropertyChanged([CallerMemberName] string member = "")
{
var eventHandler = PropertyChanged;
if (eventHandler != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(member));
}
}
}

如您所见,我正在尝试在 ViewModel.cs 中实现本地服务器和动态层,例如

public async void CreateLocalServiceAndDynamicLayer()
{
LocalMapService localMapService = new LocalMapService(this.MAPKMap);
await localMapService.StartAsync();

ArcGISDynamicMapServiceLayer arcGISDynamicMapServiceLayer = new ArcGISDynamicMapServiceLayer()
{
ID = "mpklayer",
ServiceUri = localMapService.UrlMapService,
};

//myModel.Map.Layers.Add(arcGISDynamicMapServiceLayer);
}

但我不知道如何将此服务绑定(bind)到 Model ?我试过了

myModel.Map.Layers.Add(arcGISDynamicMapServiceLayer);

但如您所知,myModel 没有任何 Map 对象。

更新

using M_PK2.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using Esri.ArcGISRuntime.LocalServices;
using Esri.ArcGISRuntime.Controls;
using Esri.ArcGISRuntime.Layers;

namespace M_PK2.ViewModels
{
class ViewModel : ViewModelBase
{
private readonly LocalMapService localMapService;
private readonly Model myModel;
private LayerCollection layers;

public ViewModel()
{
myModel = new Model();
layers = new LayerCollection();
localMapService = new LocalMapService(myModel.MapPackage);
starting += onStarting;
starting(this, EventArgs.Empty);
}

private event EventHandler starting = delegate { };
private async void onStarting(object sender, EventArgs args)
{
starting -= onStarting; //optional

// the following runs on background thread
await localMapService.StartAsync();

// returned to the UI thread

var serviceLayer = new ArcGISDynamicMapServiceLayer()
{
ID = "mpklayer",
ServiceUri = localMapService.UrlMapService,
};

Layers.Add(serviceLayer);
OnPropertyChanged(nameof(Layers)); //Notify UI
}


public LayerCollection Layers
{
get
{
return layers;
}
}
}
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };

protected void OnPropertyChanged([CallerMemberName] string member = "")
{
PropertyChanged(this, new PropertyChangedEventArgs(member));
}
}
}

最佳答案

避免使用 async void 除了事件处理程序,

引用 Async/Await - Best Practices in Asynchronous Programming

在您的情况下,您正在混合属于 View 的 UI 问题。 View 模型应该公开 View 执行其功能所需的内容。

由于所使用的依赖项 LocalMapService 的异步性质,您应该创建一个异步事件处理程序来管理获取服务 URI,并在该任务完成时通过绑定(bind)的属性更改事件通知 UI。

例如

public class ViewModel : ViewModelBase {
private readonly LocalMapService localMapService;
private readonly Model myModel;
private string serviceUri;

public ViewModel() {
myModel = new Model();
localMapService = new LocalMapService(myModel.MapPackage);
starting += onStarting;
starting(this, EventArgs.Empty);
}

private event EventHandler starting = delegate { };
private async void onStarting(object sender, EventArgs args) {
starting -= onStarting; //optional

// the following runs on background thread
await localMapService.StartAsync();

// returned to the UI thread
ServiceUri = localMapService.UrlMapService; //notifies UI
}

public string ServiceUri {
get { return serviceUri; }
set {
serviceUri = value;
OnPropertyChanged();
}
}
}

public class ViewModelBase : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged = delegate { };

protected void OnPropertyChanged([CallerMemberName] string member = "") {
PropertyChanged(this, new PropertyChangedEventArgs(member));
}
}

这样在服务异步启动后,UI 将收到更改通知。

<!-- Add a MapView Control. -->
<esriControls:MapView x:Name="MapView1">

<!-- Add a Map. -->
<esriControls:Map>

<!-- Add an ArcGISDynamicMapServiceLayer via XAML. -->
<esriLayers:ArcGISDynamicMapServiceLayer ID="mpklayer"
ServiceUri="{Bind ServiceUri}"/>
</esriControls:Map>
</esriControls:MapView>

如果目标是能够操纵多层,那么我建议绑定(bind)到 Map.Layers Property能够直接访问 View 模型中的层集合。

View 模型最终可能看起来像

public class ViewModel : ViewModelBase {
private readonly LocalMapService localMapService;
private readonly Model myModel;
private LayerCollection layers;

public ViewModel() {
myModel = new Model();
layers = new LayerCollection();
localMapService = new LocalMapService(myModel.MapPackage);
starting += onStarting;
starting(this, EventArgs.Empty);
}

private event EventHandler starting = delegate { };
private async void onStarting(object sender, EventArgs args) {
starting -= onStarting; //optional

// the following runs on background thread
await localMapService.StartAsync();

// returned to the UI thread

var serviceLayer = new ArcGISDynamicMapServiceLayer() {
ID = "mpklayer",
ServiceUri = localMapService.UrlMapService,
};

Layers.Add(serviceLayer);
}

public LayerCollection Layers {
get {
return layers;
}
}
}

和 View

<!-- Add a MapView Control. -->
<esriControls:MapView x:Name="MapView1">

<!-- Add a Map. with layers via binding-->
<esriControls:Map Layers="{Bind Layers, Mode=OneWay}" />
</esriControls:MapView>

您现在可以根据需要通过代码操作图层

关于c# - 使用 ArcGIS Runtime 本地服务器实现 MVVM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53419823/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com