在之前博客里的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(client_getHSYBInfoCompleted);
client.getHSYBInfoAsync(name.Trim());
getXQYJInfoSoapClient client2 = new getXQYJInfoSoapClient();
client2.GetAllSWZCompleted += new EventHandler(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(client_getHSYBInfoCompleted);
client.getHSYBInfoAsync(name.Trim());
//水位站数据
getXQYJInfoSoapClient client2 = new getXQYJInfoSoapClient();
client2.GetAllSWZCompleted += new EventHandler(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();
}
///
/// 更新大小
///
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 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方法或直接实例化带参数的构造函数都可以。