ArcGIS API for Silverlight 滑鼠移入移出地圖要素彈出視窗(優化處理)

暖楓無敵發表於2012-05-30

     在之前部落格裡的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方法或直接例項化帶引數的建構函式都可以。

相關文章