Bing 地图和 MVVM

发布于 2024-10-01 12:41:37 字数 16019 浏览 0 评论 0原文

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

例子: Bing map

有一些要求,它必须支持拖放并且我们必须使用MVVM(模型视图视图-模型)。现在,我们已经通过使用带有图像子数组的 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>

I'm trying to do a school project where we are to create a Silverlight application that uses bing map as a kind of map editor for placement of chargeable stations for cars.

Example:
Bing map

There are some requirements, it must support drag and drop and we must use MVVM (Model View View-Model). Now we have finished the drag and drop feature by the having a MapLayer with an array of Image children, and then hooked up events that enable drag and drop (See the code under). But now we face a problem, how can we hook up a ViewModel to this, I simply just can’t see it :(

I am not asking for a complete solution, but some help would be great.

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

My WPF code

<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>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

木格 2024-10-08 12:41:37

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

与其说将代码“转换”为 MVVM,不如说以这种方式“重做”它。

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

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

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

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

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

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

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

祝您成功。

I hate to tell you this, but the code you already wrote looks nothing like WPF or MVVM code. You are doing this in a very WinForms-ish way.

It won't be so much "converting" your code to MVVM as "redoing" it that way.

The first thing you want to ask is, "what should I have in my model?" Obviously the model consists of a list of objects such as homes and power plants. Each of these objects has at least a type and a location.

I recommend you define some kind of MappableObject class and use an ObservableCollection in your model to store your mappable objects.

Your main control should obviously be an ItemsControl that uses a Canvas for its ItemsPanel. The item template must set Canvas.Left and Canvas.Top to match the item's location. You would need a converter to convert from a Location to a Point.

Now if your ItemsControl has its ItemsSource bound to your ObservableCollection, every time a mappable object is added to the collection it will appear in its Location. Any time you change its Location it will move to the new place on the screen.

You will need something to handle the drag events and show the cursor. I would use code roughly like what you already have, except put it inside a UserControl that is used in your ItemTemplate. It can find its container and use that to map drag coordinates to map locations. As the drag progresses it can update the MappableObject's location property. Remember to transform all coordinates onto the map using TransformToVisual instead of using local coordinates for the control.

To get the right image for an object, use a converter: Your model knows what kind of object it is, and you can name your .png files to match so your converter can easily grab the right .png out of your Images directory by constructing the Url directly from the object type.

I hope these suggestions help you get moving in the right direction. Doing this in WPF using MVVM is quite simple and much cleaner than doing the old WinForms way, but you will need to use a lot of new techinques you aren't used to so there will be a learning curve.

Best wishes for your success.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文