自定义扩展元素选择工具(命名为SelectElementEx),该工具继承至ControlsSelectToolClass类,重写OnMouseUp事件,事件处理函数中,添加以下关键代码:
public override void OnMouseUp(int button, int shift, int x, int y)
{
IPage page = m_hookHelper.PageLayout.Page;
IGraphicsContainer gc = m_hookHelper.PageLayout as IGraphicsContainer;
IMapFrame mf = gc.FindFrame(m_hookHelper.FocusMap) as IMapFrame;
if (null == mf || !_hasMoved)
{
base.OnMouseUp(button, shift, x, y);//默认处理
return;
}
IElement ele = mf as IElement;
#region 移动之前的外框矩形
IEnvelope en1 = new EnvelopeClass();
ele.QueryBounds(m_hookHelper.ActiveView.ScreenDisplay, en1);
#endregion
base.OnMouseUp(button, shift, x, y);//默认处理(包括移动元素等)
IGraphicsContainerSelect pGraphicsContainerSelect = m_hookHelper.PageLayout as IGraphicsContainerSelect;
if (null == pGraphicsContainerSelect ||
pGraphicsContainerSelect.ElementSelectionCount <= 0||
!pGraphicsContainerSelect.ElementSelected(mf as IElement))
{
return;
}
//若选中元素中有Mapframe,则做限定Mapframe位置处理
limitMapFreamRangeAndPosition(gc, ele, page, en1);
}
/// <summary>
/// 限定Mapframe位置,使之始终保持在打印页面内
/// </summary>
private void limitMapFreamRangeAndPosition(IGraphicsContainer gc,IElement ele,IPage page,IEnvelope en1)
{
double width, height;
page.QuerySize(out width, out height);//纸张大小,比如A4就是210,297
IEnvelope en2 = new EnvelopeClass();
ele.QueryBounds(m_hookHelper.ActiveView.ScreenDisplay, en2);
//若超出打印页面范围,作相关处理使之始终在打印页面范围内
if (en2.XMin < 0 || en2.XMax - width > 0.00001 ||
en2.YMin < 0 || en2.YMax - height > 0.00001)
{
#region 移动(大小不改变)
if (Math.Abs(en2.Width - en1.Width) < 0.000000001 &&
Math.Abs(en2.Height - en1.Height) < 0.000000001)
{
#region 方案一,移回原地
//IDisplayTransformation trans = m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation;
//ITransform2D tr2D = ele as ITransform2D;
//tr2D.Move(en1.XMin - en.XMin, en1.YMin - en.YMin);
#endregion
#region 方案二,贴边
if (en2.XMin < 0) //拖出左边界
{
//①当Mapframe部分拖出打印页面的时候,以下两句顺便没有要求。
//②当直接MapFrame全部拖出打印页面的时候,以下两句调用顺序不能换,因为如果先赋值XMin,在没调用en2.XMax = en1.Width;之前,
//会造成XMin>XMax的现象,arcgis内部会做调整,使得XMin小于XMax,从而得不到我们想要的效果。
en2.XMax = en1.Width;
en2.XMin = 0;
}
if (en2.XMax - width > 0.0000001)//拖出右边界
{
//道理同上,若以下两行代码调用顺序调换,则在Mapframe全部拖出打印页面的时候,会出现bug
en2.XMin = width - en1.Width;
en2.XMax = width;
}
if (en2.YMax - height > 0.0000001)//拖出上边界
{
//一下两句调用顺序同理
en2.YMin = height - en1.Height;
en2.YMax = height;
}
if (en2.YMin < 0) //拖出下边界
{
//一下两句调用顺序同理
en2.YMax = en1.Height;
en2.YMin = 0;
}
#endregion
}
#endregion
#region 拉动(大小改变)
else
{
#region 如果拉出边界,贴边处理
//从上边拉出边界
en2.YMax = en2.YMax > height ? height : en2.YMax;
//从下边拉出边界
en2.YMin = en2.YMin < 0 ? 0 : en2.YMin;
//从左边拉出边界
en2.XMin = en2.XMin < 0 ? 0 : en2.XMin;
//从右边拉出边界
en2.XMax = en2.XMax > width ? width : en2.XMax;
#endregion
//矩形范围基本上没有的情况
if (en2.Width < 0.00001 || en2.Height < 0.00001)
{
#region 处理宽度
//其实此时,XMax和XMin是相等的
if (en2.XMax == 0 && en2.XMin == 0)
{
en2.XMax = en1.Width;
}
else if (en2.XMin == width && en2.XMax == width)
{
en2.XMax = width - en1.Width;
}
#endregion
#region 处理高度
//其实此时,YMax和YMin是相等的
if (en2.YMax == 0 && en2.YMin == 0)
{
en2.YMax = en1.Height;
}
else if (en2.YMax == height && en2.YMax == height)
{
en2.YMax = height - en1.Height;
}
#endregion
}//若变小了,则设置范围等于原来的(即保持不变)
else if (en2.Width - en1.Width < 0 || en2.Height - en1.Height < 0)
{
#region 处理宽度
if (en2.XMax == width)
{
en2.XMin = width - en1.Width;
}
else if (en2.XMin == 0)
{
en2.XMax = en1.Width;
}
#endregion
#region 处理高度
if (en2.YMax == height)
{
en2.YMin = height - en1.Height;
}
else if (en2.YMin == 0)
{
en2.YMax = en1.Height;
}
#endregion
}
}
#endregion
//调整Mapframe的范围和位置,使之始终保持在打印页面范围内
ele.Geometry = en2;
//更新
gc.UpdateElement(ele);
return;
}
}