ArcGIS API for Silverlight 鼠标移入移出地图要素弹出窗口(优化处理)

     在之前博客里的ArcGIS API for Silverlight 弹出框实例中,是通过点击地图要素,弹出框,但是由于没有控制元素个数,只是通过显示隐藏来进行的话,在鼠标移入和移出操作中,会出现鼠标移入的时候,总不能立刻弹出框,而是需要多次才行,用户体验较差,现在通过控制加入一个弹出框,移出时去除刚加入的弹出框,严格控制弹出框个数来实现。


核心代码如下:

//鼠标移入事件
 graphic.MouseEnter += new MouseEventHandler(swz_graphic_MouseEnter);
 graphic.MouseLeave += new MouseEventHandler(swz_graphic_MouseLeave);

void swz_graphic_MouseEnter(object sender, MouseEventArgs e)
{
            Point p = e.GetPosition(LayoutRoot);
            p.X = p.X - 40;
            p.Y = p.Y - 165;

            //鼠标左键,显示ToolTip信息
            Graphic g = sender as Graphic;
            tip_Base.g_TipSW_LeftBottom = new TipSW_LeftBottom(this, p, g.Attributes["SWZMC"].ToString(), g.Attributes["SWZBM"].ToString());
}


 void swz_graphic_MouseLeave(object sender, MouseEventArgs e)
{
            tip_Base.g_TipSW_LeftBottom.closeWindow(this);
}
public partial class TipSW_LeftBottom : UserControl
{
        MainPage mp;
        string l_name;
        string l_swzbm;


        public TipSW_LeftBottom()
        {
            InitializeComponent();
        }


        public TipSW_LeftBottom(MainPage mp, Point p, string name, string swzbm)
        {
            InitializeComponent();
            this.mp = mp;


            this.l_name = name;
            this.l_swzbm = swzbm;


            //处理标题的间距问题
            string tmp = name;
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < tmp.Length; i++)
            {
                sb.Append(tmp[i] + " ");
            }
            this.title.Content = sb.ToString();
            //绑定洪水预报的数据
            getDataSoapClient client = new getDataSoapClient();
            client.getHSYBInfoCompleted += new EventHandler<getHSYBInfoCompletedEventArgs>(client_getHSYBInfoCompleted);
            client.getHSYBInfoAsync(name.Trim());


            getXQYJInfoSoapClient client2 = new getXQYJInfoSoapClient();
            client2.GetAllSWZCompleted += new EventHandler<GetAllSWZCompletedEventArgs>(client_GetAllSWZCompleted);
            client2.GetAllSWZAsync();


            this.Margin = new Thickness(p.X, p.Y, 0, 0);
            mp.LayoutRoot.Children.Add(this);
        }




        #region 通用方法,只需要更改Show,在实例化窗体的时候,传入不同的参数即可


        private Point _location;
        private bool _isShowing;
        private Popup _popup;
        private Grid _grid;
        private Canvas _canvas;
        private FrameworkElement _content;


        //初始化并显示弹出窗体.公共方法在显示菜单项时调用
        public void Show(Point location, string name,string swzbm)
        {
            this.l_name = name;
            this.l_swzbm = swzbm;


            if (_isShowing)
                throw new InvalidOperationException();
            _isShowing = true;
            _location = location;
            ConstructPopup(this);
            _popup.IsOpen = true;


            //处理标题的间距问题
            string tmp = name;
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < tmp.Length; i++)
            {
                sb.Append(tmp[i] + " ");
            }
            this.title.Content = sb.ToString();
            //绑定洪水预报的数据
            getDataSoapClient client = new getDataSoapClient();
            client.getHSYBInfoCompleted += new EventHandler<getHSYBInfoCompletedEventArgs>(client_getHSYBInfoCompleted);
            client.getHSYBInfoAsync(name.Trim());
            //水位站数据
            getXQYJInfoSoapClient client2 = new getXQYJInfoSoapClient();
            client2.GetAllSWZCompleted += new EventHandler<GetAllSWZCompletedEventArgs>(client_GetAllSWZCompleted);
            client2.GetAllSWZAsync();
        }


        public void Show(Point location)
        {
            if (_isShowing)
                throw new InvalidOperationException();
            _isShowing = true;
            _location = location;
            ConstructPopup(this);
            _popup.IsOpen = true;
        }


        //关闭弹出窗体
        public void Close()
        {
            _isShowing = false;
            if (_popup != null)
            {
                _popup.IsOpen = false;
            }
        }


        //弹出框外面点击则关闭该窗口
        protected virtual void OnClickOutside()
        {
            Close();
        }


        // 用Grid来布局,初始化弹出窗体
        //在Grid里面添加一个Canvas,用来监测菜单项外面的鼠标点击事件
        private void ConstructPopup(FrameworkElement _element)
        {
            if (_popup != null)
                return;
            _popup = new Popup();
            _grid = new Grid();
            _popup.Child = _grid;
            _canvas = new Canvas();
            _canvas.MouseLeftButtonDown += (sender, args) => { OnClickOutside(); };
            _canvas.MouseRightButtonDown += (sender, args) => { args.Handled = true; OnClickOutside(); };
            _canvas.Background = new SolidColorBrush(Colors.Transparent);
            _grid.Children.Add(_canvas);
            _content = _element;
            _content.HorizontalAlignment = HorizontalAlignment.Left;
            _content.VerticalAlignment = VerticalAlignment.Top;
            _content.Margin = new Thickness(_location.X, _location.Y, 0, 0);
            _grid.Children.Add(_content);
            UpdateSize();
        }


        /// <summary>
        /// 更新大小
        /// </summary>
        private void UpdateSize()
        {
            _grid.Width = Application.Current.Host.Content.ActualWidth;
            _grid.Height = Application.Current.Host.Content.ActualHeight;
            if (_canvas != null)
            {
                _canvas.Width = _grid.Width;
                _canvas.Height = _grid.Height;
            }
        }


        #endregion


        #region WebService 调用方法及关闭窗体方法
        void client_GetAllSWZCompleted(object sender, GetAllSWZCompletedEventArgs e)
        {
            try
            {
                ObservableCollection<RiverFall> lists = e.Result;
                foreach (RiverFall item in lists)
                {
                    if (item.SWZBM == l_swzbm)
                    {
                        this.dt.Content = item.DTNow.ToString("yyyy年M月d日H时");
                        this.sw.Content = "水位:" + item.SW.ToString("N2") + "m";
                    }
                }
            }
            catch (Exception ex)
            {
                this.dt.Content = "没有监测到该站点数据";
                this.sw.Content = "";
            }
        }


        void client_getHSYBInfoCompleted(object sender, getHSYBInfoCompletedEventArgs e)
        {
            try
            {
                IList<洪水预报> ret = e.Result;
                if (ret.Count > 0)
                {
                    foreach (洪水预报 r in ret)
                    {
                        this.tbhsyb.Text = r.标题.Length > 9 ? r.标题.Substring(0, 7) + "..." : r.标题;
                        this.tbhsyb.Foreground = new SolidColorBrush(Colors.Red);
                    }
                }
                else
                {
                    this.tbhsyb.Text = "暂无预报";
                    this.tbhsyb.Foreground = new SolidColorBrush(Colors.Black);
                }
            }
            catch
            {
            }
        }

        //用于移除刚加入的弹出框,在主窗体鼠标移出后,调用此方法
        public void closeWindow(MainPage mp)
        {
             mp.LayoutRoot.Children.RemoveAt(mp.LayoutRoot.Children.Count - 1);
        }
        #endregion

    }
这里代码中仍然保留了原先的点击弹出框的Show方法,可以根据需要调用Show方法或直接实例化带参数的构造函数都可以。

上一篇:Android -- 保存文件


下一篇:duilib relativepos属性导致控件错误的bug修复