gpt4 book ai didi

wpf - 必应 map 和 MVVM

转载 作者:行者123 更新时间:2023-12-03 10:21:12 25 4
gpt4 key购买 nike

我正在尝试做一个学校项目,我们将在其中创建一个 Silverlight 应用程序,该应用程序使用 bing map 作为一种 map 编辑器,用于放置汽车充电站。

例子:
Bing map

有一些要求,它必须支持拖放,我们必须使用 MVVM (Model View View-Model)。现在我们已经完成了拖放功能,拥有一个带有 Image 子数组的 MapLayer,然后连接了启用拖放的事件(参见下面的代码)。但是现在我们面临一个问题,我们如何将 ViewModel 连接到这个,我根本看不到它:(

我并不是要一个完整的解决方案,但一些帮助会很棒。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.IO;
using Microsoft.Maps.MapControl;

namespace BingMapDragDrop
{
public partial class MainPage : UserControl
{
private MapAddType AddType = MapAddType.None;
private Location _myhome = new Location(55.6686512716393, 12.5481431962938, 0);

private MapLayer EndNodeLayer;
private double HideEndNodeLayer = 10.0;
private MapLayer EndNodeIntermediatedLayer;
private double HideEndNodeIntermediatedLayer = 10.0;
private MapLayer RootNodeLayer;
private double HideRootNodeLayer = 0.0;
private MapLayer RootNodeIntermediatedLayer;
private double HideRootNodeIntermediatedLayer = 5.0;

public MainPage()
{
EndNodeLayer = new MapLayer();
EndNodeIntermediatedLayer = new MapLayer();
RootNodeLayer = new MapLayer();
RootNodeIntermediatedLayer = new MapLayer();


InitializeComponent();
BingMap.SetView(_myhome, 15);
BingMap.ViewChangeOnFrame += new EventHandler<MapEventArgs>(BingMap_ViewChangeOnFrame);

// Adding the layers
BingMap.Children.Add(EndNodeIntermediatedLayer);
BingMap.Children.Add(EndNodeLayer);
BingMap.Children.Add(RootNodeIntermediatedLayer);
BingMap.Children.Add(RootNodeLayer);
}

private void AddEndNode(Location location, MapAddType type)
{
string url;

if (type == MapAddType.Home)
url = "Images/Home.png";
else if (type == MapAddType.HomeWithChargingSpot)
url = "Images/HomeWithChargingSpot.png";
else if (type == MapAddType.Workplace)
url = "Images/Workplace.png";
else if (type == MapAddType.WorkplaceWithChargingSpot)
url = "Images/WorkplaceWithChargingSpot.png";
else if (type == MapAddType.PublicChargningSpot)
url = "Images/PublicChargningSpot.png";
else if (type == MapAddType.FastChargingStation)
url = "Images/FastChargingStation.png";
else
return;

var image = new Image
{
Source = new BitmapImage(new Uri(url, UriKind.RelativeOrAbsolute)),
Width = 50,
Height = 50
};
AddImageToLayerAsDragAbleObject(image, location, EndNodeLayer);
}
private void AddPowerPlant(Location location)
{
var image = new Image
{
Source = new BitmapImage(new Uri("Images/Powerplant-New.png", UriKind.RelativeOrAbsolute)),
Width = 50,
Height = 50
};
AddImageToLayerAsDragAbleObject(image, location, EndNodeLayer);
}

#region Bing Map Events, not related to D&D
// Some events dose not exists so we need to make some our self.
private double bingZoom = 0.0;
void BingMap_ViewChangeOnFrame(object sender, MapEventArgs e)
{
if (BingMap.ZoomLevel != bingZoom)
{
bingZoom = BingMap.ZoomLevel;
BingMapZoomLevelChanged(sender, e);
}
}

private void BingMap_Loaded(object sender, RoutedEventArgs e)
{

}
private void BingMap_MouseClick(object sender, MapMouseEventArgs e)
{
if(AddType == MapAddType.None)
return;

Location loc;
if (!BingMap.TryViewportPointToLocation(e.ViewportPoint, out loc))
return;

switch (AddType)
{
case MapAddType.Powerplant:
AddPowerPlant(loc);
break;
case MapAddType.FastChargingStation:
case MapAddType.PublicChargningSpot:
case MapAddType.WorkplaceWithChargingSpot:
case MapAddType.Workplace:
case MapAddType.HomeWithChargingSpot:
case MapAddType.Home:
AddEndNode(loc, AddType);
break;
}

AddType = MapAddType.None;
}
private void BingMapZoomLevelChanged(object sender, MapEventArgs e)
{
if (BingMap.ZoomLevel <= HideEndNodeLayer && EndNodeLayer.Visibility == Visibility.Visible)
EndNodeLayer.Visibility = Visibility.Collapsed;
else if (BingMap.ZoomLevel > HideEndNodeLayer && EndNodeLayer.Visibility == Visibility.Collapsed)
EndNodeLayer.Visibility = Visibility.Visible;

if (BingMap.ZoomLevel >= HideEndNodeIntermediatedLayer && EndNodeLayer.Visibility == Visibility.Visible)
EndNodeIntermediatedLayer.Visibility = Visibility.Collapsed;
else if (BingMap.ZoomLevel > HideEndNodeIntermediatedLayer && EndNodeLayer.Visibility == Visibility.Collapsed)
EndNodeIntermediatedLayer.Visibility = Visibility.Visible;

if (BingMap.ZoomLevel <= HideRootNodeLayer && EndNodeLayer.Visibility == Visibility.Visible)
RootNodeLayer.Visibility = Visibility.Collapsed;
else if (BingMap.ZoomLevel > HideRootNodeLayer && EndNodeLayer.Visibility == Visibility.Collapsed)
RootNodeLayer.Visibility = Visibility.Visible;

if (BingMap.ZoomLevel <= HideRootNodeIntermediatedLayer && EndNodeLayer.Visibility == Visibility.Visible)
RootNodeIntermediatedLayer.Visibility = Visibility.Collapsed;
else if (BingMap.ZoomLevel > HideRootNodeIntermediatedLayer && EndNodeLayer.Visibility == Visibility.Collapsed)
RootNodeIntermediatedLayer.Visibility = Visibility.Visible;
}
#endregion

#region This is where the dragging magic happens
private void AddImageToLayerAsDragAbleObject(Image image, Location location, MapLayer mapLayer)
{
image.MouseLeftButtonDown += new MouseButtonEventHandler(ImageMouseLeftButtonDown);
var position = PositionOrigin.Center;
mapLayer.AddChild(image, location, position);
}

private bool _isDragging = false;
private Image _dragingObject;
private void ImageMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
_isDragging = true;
// We need to save the object, so we are able to set the location on release
_dragingObject = (Image)sender;

// Here we add the events, be sure to remove them at release!
BingMap.MousePan += new EventHandler<MapMouseDragEventArgs>(BingMapMousePan);
BingMap.MouseLeftButtonUp += new MouseButtonEventHandler(BingMapMouseLeftButtonUp);
BingMap.MouseMove += new MouseEventHandler(BingMapMouseMove);
}
// Event that is called when an image is move
private void BingMapMouseMove(object sender, MouseEventArgs e)
{
var map = (Map)sender;
if (!_isDragging) return;
// The the location of the mouse
var mouseMapPosition = e.GetPosition(map);
var mouseGeocode = map.ViewportPointToLocation(mouseMapPosition);

// Set location
MapLayer.SetPosition(_dragingObject, mouseGeocode);
}
// Event that is called when an image is released
private void BingMapMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
// Remove the events
BingMap.MousePan -= BingMapMousePan;
BingMap.MouseLeftButtonUp -= BingMapMouseLeftButtonUp;
BingMap.MouseMove -= BingMapMouseMove;
// Disable dragging
_isDragging = false;
}
// Event that is called when the map is panning
private void BingMapMousePan(object sender, MapMouseDragEventArgs e)
{
// We don't want the map to pan if we are dragging
if (_isDragging)
e.Handled = true;
}
#endregion

#region Menu
private void MenuMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if ((String)((Image)sender).Tag == "Powerplant")
AddType = AddType == MapAddType.Powerplant ? MapAddType.None : MapAddType.Powerplant;

if ((String)((Image)sender).Tag == "Home")
AddType = AddType == MapAddType.Home ? MapAddType.None : MapAddType.Home;

if ((String)((Image)sender).Tag == "HomeWithChargingSpot")
AddType = AddType == MapAddType.HomeWithChargingSpot ? MapAddType.None : MapAddType.HomeWithChargingSpot;

if ((String)((Image)sender).Tag == "Workplace")
AddType = AddType == MapAddType.Workplace ? MapAddType.None : MapAddType.Workplace;

if ((String)((Image)sender).Tag == "WorkplaceWithChargingSpot")
AddType = AddType == MapAddType.WorkplaceWithChargingSpot ? MapAddType.None : MapAddType.WorkplaceWithChargingSpot;

if ((String)((Image)sender).Tag == "PublicChargningSpot")
AddType = AddType == MapAddType.PublicChargningSpot ? MapAddType.None : MapAddType.PublicChargningSpot;

if ((String)((Image)sender).Tag == "FastChargingStation")
AddType = AddType == MapAddType.FastChargingStation ? MapAddType.None : MapAddType.FastChargingStation;
}
#endregion

#region Cursor image

private bool IsCursorImageSet = false;

private void UserControl_MouseMove(object sender, MouseEventArgs e)
{
PlaceCursorImage(e.GetPosition(this));
}
private void UserControl_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
PlaceCursorImage(e.GetPosition(this));
}
private void PlaceCursorImage(Point location)
{
if (AddType == MapAddType.None && !IsCursorImageSet)
return;
if (AddType == MapAddType.None && IsCursorImageSet)
{
IsCursorImageSet = false;
CursorImage.Visibility = Visibility.Collapsed;
return;
}

Canvas.SetTop(CursorImage, location.Y + 5.0);
Canvas.SetLeft(CursorImage, location.X + 5.0);

if (!IsCursorImageSet)
{
IsCursorImageSet = true;

switch (AddType)
{
case MapAddType.Powerplant:
CursorImage.Source =
new BitmapImage(new Uri("Images/Powerplant-New.png", UriKind.RelativeOrAbsolute));
break;
case MapAddType.Home:
CursorImage.Source =
new BitmapImage(new Uri("Images/Home.png", UriKind.RelativeOrAbsolute));
break;
case MapAddType.HomeWithChargingSpot:
CursorImage.Source =
new BitmapImage(new Uri("Images/HomeWithChargingSpot.png", UriKind.RelativeOrAbsolute));
break;
case MapAddType.Workplace:
CursorImage.Source =
new BitmapImage(new Uri("Images/Workplace.png", UriKind.RelativeOrAbsolute));
break;
case MapAddType.WorkplaceWithChargingSpot:
CursorImage.Source =
new BitmapImage(new Uri("Images/WorkplaceWithChargingSpot.png", UriKind.RelativeOrAbsolute));
break;
case MapAddType.PublicChargningSpot:
CursorImage.Source =
new BitmapImage(new Uri("Images/PublicChargningSpot.png", UriKind.RelativeOrAbsolute));
break;
case MapAddType.FastChargingStation:
CursorImage.Source =
new BitmapImage(new Uri("Images/FastChargingStation.png", UriKind.RelativeOrAbsolute));
break;
default:
return;
}

CursorImage.Visibility = Visibility.Visible;
CursorImage.Width = 40;
CursorImage.Height = 40;
CursorImage.Stretch = Stretch.Uniform;
}
}
#endregion
}
}

我的 WPF 代码
<UserControl x:Class="BingMapDragDrop.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="clr-namespace:Microsoft.Maps.MapControl;assembly=Microsoft.Maps.MapControl"
mc:Ignorable="d" MouseMove="UserControl_MouseMove" Width="800" Height="600" MouseLeftButtonUp="UserControl_MouseLeftButtonUp">
<Canvas IsHitTestVisible="True">
<StackPanel HorizontalAlignment="Left" Name="stackPanelMenu" Width="75" Margin="0,12,0,12" Canvas.Top="0" Height="588">
<Image Name="imagePowerplant" Stretch="Uniform" Width="35" Source="/BingMapDragDrop;component/Images/Powerplant-New.png" Tag="Powerplant" MouseLeftButtonUp="MenuMouseLeftButtonUp" />
<Image Name="imageHome" Stretch="Uniform" Width="35" Source="/BingMapDragDrop;component/Images/Home.png" Tag="Home" MouseLeftButtonUp="MenuMouseLeftButtonUp" />
<Image Name="imageHomeWithChargingSpot" Stretch="Uniform" Width="35" Source="/BingMapDragDrop;component/Images/HomeWithChargingSpot.png" Tag="HomeWithChargingSpot" MouseLeftButtonUp="MenuMouseLeftButtonUp" />
<Image Name="imageWorkplace" Stretch="Uniform" Width="35" Source="/BingMapDragDrop;component/Images/Workplace.png" Tag="Workplace" MouseLeftButtonUp="MenuMouseLeftButtonUp" />
<Image Name="imageWorkplaceWithChargingSpot" Stretch="Uniform" Width="35" Source="/BingMapDragDrop;component/Images/WorkplaceWithChargingSpot.png" Tag="WorkplaceWithChargingSpot" MouseLeftButtonUp="MenuMouseLeftButtonUp" />
<Image Name="imagePublicChargningSpot" Stretch="Uniform" Width="35" Source="/BingMapDragDrop;component/Images/PublicChargningSpot.png" Tag="PublicChargningSpot" MouseLeftButtonUp="MenuMouseLeftButtonUp" Height="49" />
<Image Name="imageFastChargingStation" Stretch="Uniform" Width="35" Source="/BingMapDragDrop;component/Images/FastChargingStation.png" Tag="FastChargingStation" MouseLeftButtonUp="MenuMouseLeftButtonUp" />
</StackPanel>
<m:Map x:Name="BingMap" CredentialsProvider="[Insert credentials here]" Mode="Aerial" Loaded="BingMap_Loaded" MouseClick="BingMap_MouseClick" Canvas.Left="72" Canvas.Top="0" Margin="0" Height="600" Width="728" />

<Image Name="CursorImage" Visibility="Collapsed" IsHitTestVisible="False" Opacity="0.5" />
</Canvas>
</UserControl>

最佳答案

我不想告诉你这一点,但你已经编写的代码看起来不像 WPF 或 MVVM 代码。您正在以一种非常类似于 WinForms 的方式执行此操作。

将您的代码“转换”为 MVVM 并不会像那样“重做”它。

您要问的第一件事是,“我的模型中应该有什么?”显然,该模型由一系列对象组成,例如房屋和发电厂。这些对象中的每一个都至少有一个类型和一个位置。

我建议您定义某种 MappableObject 类并在模型中使用 ObservableCollection 来存储您的可映射对象。

您的主控件显然应该是使用 Canvas 作为其 ItemsPanel 的 ItemsControl。项目模板必须设置 Canvas.Left 和 Canvas.Top 以匹配项目的位置。您需要一个转换器来将位置转换为点。

现在,如果您的 ItemsControl 将其 ItemsSource 绑定(bind)到您的 ObservableCollection,则每次将可映射对象添加到集合中时,它都会出现在其 Location 中。每当您更改其位置时,它都会移动到屏幕上的新位置。

您将需要一些东西来处理拖动事件并显示光标。我将使用与您已经拥有的代码大致相同的代码,只是将它放在您的 ItemTemplate 中使用的 UserControl 中。它可以找到它的容器并使用它来将拖动坐标映射到 map 位置。随着拖动的进行,它可以更新 MappableObject 的 location 属性。请记住使用 TransformToVisual 将所有坐标转换到 map 上,而不是使用控件的局部坐标。

要为对象获取正确的图像,请使用转换器:您的模型知道它是什么类型的对象,并且您可以命名您的 .png 文件以匹配,以便您的转换器可以轻松地通过构造从图像目录中获取正确的 .png Url 直接来自对象类型。

我希望这些建议可以帮助您朝着正确的方向前进。在 WPF 中使用 MVVM 执行此操作比使用旧的 WinForms 方式非常简单且干净得多,但是您将需要使用许多您不习惯的新技术,因此会有一个学习曲线。

祝您成功。

关于wpf - 必应 map 和 MVVM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4144091/

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