自定义UserControl打破了XAML Designerier和Intellisense

时间:2015-04-08 21:35:32

标签: c# xaml visual-studio-2013 windows-phone-8.1

我正在使用Windows Store Universal应用程序,目前我专注于WP8.1。我创建了一个自定义UserControl,但每当我在使用XAML的视图中包含此自定义控件时,XAML Designer都无法加载设计视图。它只是显示"加载设计师......"并使用超过60%的CPU。

通常我不会关注Designer视图,因为我更喜欢直接修改XAML。问题是当设计师挂起时我失去了智能感知,这是我在编写XAML时所依赖的。

我的示例是一个适用于Windows Phone和Windows应用商店应用的地图控件,但我也遇到了其他更简单控件的问题。

有趣的是,XAML Designer在直接处理UserControl时工作正常。将UserControl包含在另一个视图的XAML中时,这只是一个问题。

我的UserControl XAML是:

<UserControl
    x:Class="MyProject.Controls.MyMapControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MyProject.Control"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300"
    d:DesignWidth="400">

    <Grid>
        <Image x:Name="image" Stretch="UniformToFill" />
    </Grid>
</UserControl>

背后的代码看起来像

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.Devices.Geolocation;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using System.Threading.Tasks;

#if WINDOWS_PHONE_APP
using Windows.UI.Xaml.Controls.Maps;
using Windows.UI.Xaml.Shapes;
#elif WINDOWS_METRO_APP
using Bing.Maps;
#endif

// The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236

namespace MyProject.Controls
{
    public sealed partial class MyMapControl : UserControl
    {
        #if WINDOWS_PHONE_APP
        private MapControl map;
        #elif WINDOWS_METRO_APP
        private Map map;
        private MapShapeLayer shapeLayer;
        #endif

        /// <summary>
        /// Creates the MyMapControl with the appropriate credentials
        /// </summary>
        public MyMapControl()
        {
            this.InitializeComponent();
            #if WINDOWS_PHONE_APP
            map = new MapControl();
            map.MapServiceToken = "{map service token goes here}";
            #elif WINDOWS_METRO_APP
            map = new Map();
            map.Credentials = "{credentials go here"};
            shapeLayer = new MapShapeLayer();
            map.ShapeLayers.Add(shapeLayer);
            #endif
            this.main_grid.Children.Add(map);
        }

        #if WINDOWS_PHONE_APP
        public double Pitch {
            get {
                return map.Pitch;
            }
            set {
                if(map.DesiredPitch != value) {
                    map.DesiredPitch = value;
                    OnPropertyChanged("Pitch");
                }
            }
        }

        public MapStyle Style {
            get {
                return map.Style;
            }
            set {
                if(value != map.Style) {
                    map.Style = value;
                    OnPropertyChanged("Style");
                }
            }
        }

        public MapColorScheme ColorScheme {
            get {
                return map.ColorScheme;
            }
            set {
                if(map.ColorScheme != value) {
                    map.ColorScheme = value;
                    OnPropertyChanged("ColorScheme");
                }
            }
        }

        private bool _ShowLocation = true;

        public bool ShowLocation {
            get {
                return this._ShowLocation;
            }
            set {
                if(this._ShowLocation != value) {
                    this._ShowLocation = value;
                    OnPropertyChanged("ShowLocation");
                }
            }
        }
        #endif

        /// <summary>
        /// Get or set the map's ZoomLevel
        /// </summary>
        public double ZoomLevel {
            get {
                return map.ZoomLevel;
            }
            set {
                if(map.ZoomLevel != value) {
                    map.ZoomLevel = value;
                    OnPropertyChanged("ZoomLevel");
                }
            }
        }

        /// <summary>
        /// Get or set the map's manipulation mode
        /// </summary>
        public Windows.UI.Xaml.Input.ManipulationModes ManipulationMode {
            get {
                return map.ManipulationMode;
            }
            set {
                map.ManipulationMode = value;
            }
        }

        /// <summary>
        /// Get or set the map's center point
        /// </summary>
        public Geopoint Center {
            get {
                #if WINDOWS_PHONE_APP
                return map.Center;
                #elif WINDOWS_METRO_APP
                return map.Center.ToGeopoint();
                #endif
            }
            set {
                #if WINDOWS_PHONE_APP
                map.Center = value;
                #elif WINDOWS_METRO_APP
                map.Center = value.ToLocation();
                #endif
                OnPropertyChanged("Center");
            }
        }

        /// <summary>
        /// Get or set the map's credentials
        /// </summary>
        public string Credentials {
            get {
                #if WINDOWS_PHONE_APP
                return map.MapServiceToken;
                #elif WINDOWS_METRO_APP
                return map.Credentials;
                #endif
            }
            set {
                if(!string.IsNullOrEmpty(value)) {
                    #if WINDOWS_PHONE_APP
                    map.MapServiceToken = value;
                    #elif WINDOWS_METRO_APP
                    map.Credentials = value;
                    #endif
                    OnPropertyChanged("Credentials");
                }
            }
        }

        /// <summary>
        /// Get or set the map's display of traffic
        /// </summary>
        public bool ShowTraffic {
            get {
                #if WINDOWS_PHONE_APP
                return map.TrafficFlowVisible;
                #elif WINDOWS_METRO_APP
                return map.ShowTraffic;
                #endif
            }
            set {
                #if WINDOWS_PHONE_APP
                map.TrafficFlowVisible = value;
                #elif WINDOWS_METRO_APP
                map.ShowTraffic = value;
                #endif
                OnPropertyChanged("ShowTraffic");
            }
        }

        /// <summary>
        /// Set the current location for the map view as well as zoom level.
        /// </summary>
        /// <param name="center">BasicGeoposition for the center of the map view</param>
        /// <param name="zoom">Zoom Level at which to display map</param>
        public void SetView(BasicGeoposition center, double zoom) {
            #if WINDOWS_PHONE_APP
            map.Center = new Geopoint(center);
            map.ZoomLevel = zoom;
            #elif WINDOWS_METRO_APP
            map.SetView(center.ToLocation(), zoom);
            #endif
            OnPropertyChanged("ZoomLevel");
            OnPropertyChanged("Center");
        }

        /// <summary>
        /// Adds a basic push pin with text to the map at a specific location.
        /// </summary>
        /// <param name="location">Location for pushpin</param>
        /// <param name="text">Text to display with pushpin</param>
        public void AddPushpin(BasicGeoposition location, string text) {
            #if WINDOWS_PHONE_APP
            Grid pin = new Grid() {
                Width = 34,
                Height = 24,
                Margin = new Thickness(-12)
            };
            pin.Children.Add(new Ellipse() {
                Fill = new SolidColorBrush(Colors.DodgerBlue),
                Stroke = new SolidColorBrush(Colors.White),
                StrokeThickness = 3,
                Width = 24,
                Height = 24
            });
            pin.Children.Add(new TextBlock() {
                Text = text,
                FontSize = 12,
                Foreground = new SolidColorBrush(Colors.White),
                HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Center,
                VerticalAlignment = Windows.UI.Xaml.VerticalAlignment.Center
            });
            MapControl.SetLocation(pin, new Geopoint(location));
            map.Children.Add(pin);
            #elif WINDOWS_METRO_APP
            Pushpin pin = new Pushpin() {
                Text = text
            };
            MapLayer.SetPosition(pin, location.ToLocation());
            map.Children.Add(pin);
            #endif
        }

        /// <summary>
        /// Adds a polygon to the map
        /// </summary>
        /// <param name="locations"></param>
        /// <param name="strokeColor"></param>
        /// <param name="strokeThickness"></param>
        public void AddPolygon(List<BasicGeoposition> locations, Color fillColor, Color strokeColor, double strokeThickness) {
            #if WINDOWS_PHONE_APP
            MapPolygon line = new MapPolygon() {
                Path = new Geopath(locations),
                StrokeColor = strokeColor,
                StrokeThickness = strokeThickness
            };
            map.MapElements.Add(line);
            #elif WINDOWS_METRO_APP
            MapPolygon line = new MapPolygon() {
                Locations = locations.ToLocationCollection(),
                FillColor = fillColor
            };
            shapeLayer.Shapes.Add(line);
            #endif
        }

        /// <summary>
        /// Clears all elements on the map
        /// </summary>
        public void ClearMap() {
            #if WINDOWS_PHONE_APP
            map.MapElements.Clear();
            #elif WINDOWS_METRO_APP
            shapeLayer.Shapes.Clear();
            #endif
            map.Children.Clear();
        }

        /// <summary>
        /// Notify Property Changed Event
        /// </summary>
        public event DependencyPropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Notify Property Changed method
        /// </summary>
        /// <param name="propertyName">Name of modified property</param>
        internal void OnPropertyChanged(string propertyName) {

        }
    }
}

0 个答案:

没有答案