MapInfo開發心得——多地圖關聯篇【轉】

 
多個窗體(MDI)同時展示,並相互操作這並不困難,小弟在這介紹一下由MapInfo中MapControl組成的多窗體關聯處理。
首先看看效果:

 

以上多關聯地圖窗體實現了:在同一個窗體中加載多個(最多4個)地圖,地圖的拖拽、縮放操作可相互關聯,每個地圖上各個數據都可以完全不相同!
 
現在我來說一下實現過程:
首先要在同一個窗體中加載多個地圖,我採用了UserControl來做:
public partial class ViewMap :System.Windows.Forms.UserControl
在這個ViewMap控件中,我把地圖控件所需要的所有東西(包括加載數據的方法、展示圖元的方法等)都封裝其中。
然後在此控件中聲明幾個事件:
聲明事件
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->        /**//// <summary>
        
/// 傳遞子控件事件到父窗體的中間事件
        
/// </summary>

        public event MouseEventHandler MapControl_MouseMove;
        
/**//// <summary>
        
/// 傳遞子控件事件到父窗體的中間事件
        
/// </summary>

        public event EventHandler ViewChanged;
        
/**//// <summary>
        
/// 控件關閉事件
        
/// </summary>

        public event EventHandler Closed;
        
/**//// <summary>
        
/// 在地圖控件上點擊後觸發
        
/// </summary>

        public event MouseEventHandler MapControl_MouseClick;

由於在ViewMap中的MapControl是私有的,MapControl的事件並不能被外界所調用,所以在此聲明兩個用於傳遞事件的中間事件,以使各地圖控件相互關聯操作。當然,這些MapControl的事件需要在ViewMap中註冊並調用:
轉發事件
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->        void mapControl1_MapControl_MouseMove ( object sender, MouseEventArgs e )
        
{
            
if ( this.MapControl_MouseMove != null )
            
{
                
//把事件轉發出去
                MapControl_MouseMove ( this, e );
            }

        }

        
void mapControl1_MapControl_MouseClick ( object sender, MouseEventArgs e )
        
{
            
if ( this.MapControl_MouseClick != null )
            
{
                MapControl_MouseClick ( 
this, e );
            }

        }

在以上代碼中,需要注意到是,我在調用MapControl_MouseMove事件時,把sender的參數轉換爲了ViewMap本身,這樣做,是爲了將來避免死循環。
那麼在需要展示多地圖的窗體上調用一下AddControl,再設置一下控件大小,座標等,就能方便地把地圖控件加載上去了。
添加子控件
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->         /**//// <summary>
        
/// 爲窗體添加子控件
        
/// </summary>
        
/// <param name="childForm">需要添加的子窗體</param>

        public void AddChildForm ( ViewMap childForm )
        
{
            
if ( !childFormList.Contains ( childForm ) )
            
{
                
if ( !( childFormList.Count + 1 > _maxChildForm ) )
                
{
                    
this.childFormList.Add ( childForm );
                }

                
else
                
{
                    MessageBox.Show ( _OVER_MAX_CHILDFORM_COUNT );
                    
return;
                }

            }

            childForm.MapControl_MouseMove 
+= new MouseEventHandler ( vm_MapControl_MouseMove );
            childForm.ViewChanged 
+= new EventHandler ( vm_ViewChanged );
            childForm.Closed 
+= new EventHandler ( childForm_Closed );
            childForm.MapControl_MouseClick 
+= new MouseEventHandler ( childForm_MapControl_MouseClick );
            SetChildFormLocation ();
            
this.Controls.Add ( childForm );
        }

在以上代碼中註冊的事件,以下是執行方法節選:
執行方法節選
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->         void vm_MapControl_MouseMove ( object sender, MouseEventArgs e )
        
{
            
foreach ( ViewMap vm in childFormList )
            
{
                
if ( !sender.Equals ( vm ) )
                
{
                    vm.DrawAssistLine ( e.Location );
                }

            }

        }


        
void vm_ViewChanged ( object sender, EventArgs e )
        
{
            
//遍歷所有子窗體,如當前sender不爲本身,執行事件
            MapControlEventArg mce = e as MapControlEventArg;
            
foreach ( ViewMap vm in childFormList )
            
{
                
if ( !sender.Equals ( vm ) )
                
{
                    vm.SetCenter ( mce.ZoomLevel, mce.Center );
                }

            }

        }

在這裏,就可以看出來使用ViewMap本身替代sender的優點了,在這裏循環判斷一下子控件列表,如果不爲控件本身,便執行相應方法……
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章