ArcGis+C#二次开发过程中重写鼠标滚轮事件,实现地图缩放功能,但在缩小的时候会出现地图闪烁的情况不知道怎么解决
private void axMapControl_OnMouseWheel(object sender, MouseEventArgs e)
{
double scale = axMapControl.MapScale;
IEnvelope mEnvelope = null;
IPoint mPoint = new PointClass();
//IPoint mousePoint = null;
mEnvelope = axMapControl.ActiveView.Extent;
mPoint.X = (mEnvelope.XMax + mEnvelope.XMin) / 2;
mPoint.Y = (mEnvelope.YMax + mEnvelope.YMin) / 2;
mousePoint = axMapControl.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(e.X, e.Y);
double moveDisX = mousePoint.X - (mEnvelope.XMax + mEnvelope.XMin) / 2;
double moveDisY = mousePoint.Y - (mEnvelope.YMax + mEnvelope.YMin) / 2;
mEnvelope.CenterAt(mousePoint);
if (e.Delta > 0)
{
mEnvelope.Width = mEnvelope.Width * 0.8;
mEnvelope.Height = mEnvelope.Height * 0.8;
mPoint.X = mousePoint.X - moveDisX * 0.8;
mPoint.Y = mousePoint.Y - moveDisY * 0.8;
mEnvelope.CenterAt(mPoint);
axMapControl.ActiveView.Extent = mEnvelope;
axMapControl.ActiveView.Refresh();
}
else if (e.Delta < 0)
{
//if(scale>=SystemConfig.DefaultBMapScale)
if(scale>=SystemConfig.DefaultTMapScale)
//if (scale >= 1900000)
{
mPoint.X = mousePoint.X - moveDisX;
mPoint.Y = mousePoint.Y - moveDisY;
//MapMouseUp();
}
else
{
mEnvelope.Width = mEnvelope.Width * 1.25;
mEnvelope.Height = mEnvelope.Height * 1.25;
mPoint.X = mousePoint.X - moveDisX * 1.25;
mPoint.Y = mousePoint.Y - moveDisY * 1.25;
//mEnvelope.CenterAt(mPoint);
axMapControl.ActiveView.Extent = mEnvelope;
//axMapControl.ActiveView.Refresh();
}
MapMouseUp();
}
}
在代码中,地图闪烁的情况可能是因为在执行缩小操作时,地图的刷新不够及时,导致视觉效果出现了不连续的情况。为了解决这个问题,可以尝试对代码进行改进,如下所示:
在进行缩小操作时,先将地图的可见范围保存下来。
对地图进行缩放操作之前,调用 IMapControl2.SuppressResizeDrawing
方法,暂时禁止地图控件的绘制。
对地图进行缩放操作之后,调用 IMapControl2.Refresh
方法,手动刷新地图控件。
以下是修改后的代码:
private void axMapControl_OnMouseWheel(object sender, MouseEventArgs e)
{
double scale = axMapControl.MapScale;
IEnvelope mEnvelope = null;
IPoint mPoint = new PointClass();
mEnvelope = axMapControl.ActiveView.Extent;
mPoint.X = (mEnvelope.XMax + mEnvelope.XMin) / 2;
mPoint.Y = (mEnvelope.YMax + mEnvelope.YMin) / 2;
IPoint mousePoint = axMapControl.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(e.X, e.Y);
double moveDisX = mousePoint.X - (mEnvelope.XMax + mEnvelope.XMin) / 2;
double moveDisY = mousePoint.Y - (mEnvelope.YMax + mEnvelope.YMin) / 2;
mEnvelope.CenterAt(mousePoint);
if (e.Delta > 0)
{
mEnvelope.Width = mEnvelope.Width * 0.8;
mEnvelope.Height = mEnvelope.Height * 0.8;
mPoint.X = mousePoint.X - moveDisX * 0.8;
mPoint.Y = mousePoint.Y - moveDisY * 0.8;
mEnvelope.CenterAt(mPoint);
}
else if (e.Delta < 0)
{
if(scale >= SystemConfig.DefaultTMapScale)
{
mPoint.X = mousePoint.X - moveDisX;
mPoint.Y = mousePoint.Y - moveDisY;
}
else
{
mEnvelope.Width = mEnvelope.Width * 1.25;
mEnvelope.Height = mEnvelope.Height * 1.25;
mPoint.X = mousePoint.X - moveDisX * 1.25;
mPoint.Y = mousePoint.Y - moveDisY * 1.25;
}
}
// 调用 IMapControl2 接口实现缩放操作
IMapControl2 mapControl2 = (IMapControl2)axMapControl.Object;
mapControl2.SuppressResizeDrawing(true); // 禁止绘制
axMapControl.ActiveView.Extent = mEnvelope; // 进行缩放操作
mapControl2.SuppressResizeDrawing(false); // 恢复绘制
axMapControl.ActiveView.Refresh(); // 手动刷新
}
在修改后的代码中,我们使用了 IMapControl2
接口的 SuppressResizeDrawing
方法来实现暂时禁止绘制和恢复绘制的功能。在进行缩放操作时,首先调用 SuppressResizeDrawing
方法禁止绘制,然后进行缩放操作,最后再调用 Refresh
方法手动刷新地图控件。这样就可以避免在缩小操作时出现地图闪烁的情况。
这种地图闪烁的现象通常是由于多次刷新地图导致的。可以尝试将地图的显示模式设置为双缓冲模式,并且在缩小地图的代码块中屏蔽掉一些不必要的刷新操作,以减少地图闪烁的问题。
具体的步骤如下:
在axMapControl_OnMouseDown中添加以下代码:
//启用地图双缓冲模式
((IMapControl4)axMapControl.Object).UseBufferedDisplay = true;
//开始缓存地图刷新操作
axMapControl.ActiveView.ScreenDisplay.StartDrawing(0, (short)esriScreenCache.esriNoScreenCache);
在axMapControl_OnMouseWheel事件的else if (e.Delta < 0)代码块中将地图刷新操作注释掉,只在需要刷新的时候刷新:
if(scale>=SystemConfig.DefaultTMapScale)
{
// do nothing
}
else
{
mEnvelope.Width = mEnvelope.Width * 1.25;
mEnvelope.Height = mEnvelope.Height * 1.25;
mPoint.X = mousePoint.X - moveDisX * 1.25;
mPoint.Y = mousePoint.Y - moveDisY * 1.25;
axMapControl.ActiveView.Extent = mEnvelope;
//仅在需要刷新的时候刷新
if (this.isNeedRefresh == true)
{
this.isNeedRefresh = false;
axMapControl.ActiveView.Refresh();
}
}
在axMapControl_OnMouseWheel事件的code block之后增加如下代码:
//停止地图缓存刷新操作
axMapControl.ActiveView.ScreenDisplay.FinishDrawing();
这样做可以避免多余的地图重绘,提高地图显示效率,同时降低地图刷新导致的闪烁现象。
Form的构造函数里加上这段就行了
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.DoubleBuffer, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
base.DoubleBuffered = true;
UpdateStyles();