在重写的panel中根据数据库的信息自动绘制一张结构图,结构图由n个图标和图标之间的连线组成,图标可以使用鼠标拖动,当图标被拖动后,图标之间的连线自动重新绘制,画线和画图标分别使用单独的组件类实现。
    现在的问题是:当有2张或2张以上的图片完全重合时,点击其中一个并拖动之,此时所有重合的图片一起移动?如何解决?

解决方案 »

  1.   

    画图标的核心代码如下(除去界面代码):
    ////////////////////////////////////////////////////////////////////
            //画图片的类
            /// /////////////////////////////////////////////////////////////////////
            
            public partial class TiePaint : Component, ISupportInitialize
            {            
                //初始化
                public void InitializeComponent()
                {
      
                }
                Pen pen1 = new Pen(System.Drawing.Color.White,3);
                PictureBox pb1 = new PictureBox();
                Image myimage1 = Image.FromFile(@"c:\tzsys\2.bmp");
                
                private ContextMenuStrip m_ContextMenu = new ContextMenuStrip();
                public ContextMenuStrip ContextMenu
                {
                    get { return m_ContextMenu; }
                    set
                    {
                        m_ContextMenu = value;
                        //if (value != null)
                        //    value.Tag =this;
                    }
                }
                private GraphPanel m_Parent = null;
                private Point m_OrgPoint = Point.Empty;
                public GraphPanel Parent
                {
                    get { return m_Parent; }
                    set { m_Parent = value; }
                }
                private bool m_Selected = false;            private bool Selected
                {
                    get { return m_Selected; }
                    set
                    {
                        if (value != this.m_Selected)
                        {
                            m_Selected = value;
                            this.m_Parent.Invalidate();
                            this.m_Parent.Update();                    }
                    }
                }
                private Point m_Point = Point.Empty;
                public Point Point1
                {
                    get { return m_Point; }
                    set { m_Point = value; }
                }
                public TiePaint()
                {
                    InitializeComponent();
                }            public TiePaint(IContainer container)
                {
                    container.Add(this);                InitializeComponent();
                }
                private void m_Parent_Paint(object sender, PaintEventArgs e)
                {
                    //画点(图片)
                    pb1.Image = myimage1;
                    pb1.Size = myimage1.Size;
                    Graphics g1 = this.Parent.CreateGraphics();
                    g1.DrawImage(myimage1, (Point1.X - myimage1.Width / 2), (Point1.Y - myimage1.Height / 2));
                    if (this.m_Selected)
                    {
                        Pen pen = new Pen(System.Drawing.Color.White,2);
                        Graphics g = this.Parent.CreateGraphics();
                        g.DrawRectangle(pen, (Point1.X - 16), (Point1.Y - 16), 32, 32);
                        
                        //g.DrawRectangle(pen, (Point1.X - myimage1.Width / 2 - 3), (Point1.Y - myimage1.Height / 2 - 3), (myimage1.Width + 6), (myimage1.Height + 6));
                    }
                }
                
                private void m_Parent_MouseDown(object sender, MouseEventArgs e)
                {
                    if (CheckMouse(e.Location))
                        this.Selected = true;
                    else
                        this.Selected = false;
                }
                private void m_Parent_MouseMove(object sender, MouseEventArgs e)
                {
                    if (!this.Selected)
                    {
                        this.m_OrgPoint = Point.Empty;
                        return;
                    }
                    if (this.m_OrgPoint == Point.Empty)
                    {
                        this.m_OrgPoint = e.Location;
                        return;
                    }
                    if (e.Button == MouseButtons.Left)
                    {
                       
                        if (this.Parent.ClientRectangle.Contains(e.Location))
                        {
                            this.m_Point.X += (e.Location.X - this.m_OrgPoint.X);
                            this.m_Point.Y += (e.Location.Y - this.m_OrgPoint.Y);
                            this.m_OrgPoint = e.Location;
                            this.m_Parent.Invalidate();
                            this.m_Parent.Update();
                        }
                        else
                        {
                            this.m_OrgPoint = Point.Empty;
                            this.Selected = false;
                        }
                    }
                }
                private void m_Parent_ContextMenuQuery(object sender, ContextMenuQueryMenuEventArgs e)
                {
                    if (this.Selected)
                    {
                        if ((!e.Handle) && (this.m_ContextMenu != null))
                        {
                            this.m_ContextMenu.Show(this.m_Parent, e.MouseEventArgs.Location);
                            e.Handle = true;
                        }
                    }
                }            private void m_Parent_MouseUp(object sender, MouseEventArgs e)
                {
                    //this.Selected = false;
                    this.m_OrgPoint = Point.Empty;
                    int a = 0;
                    int b = 0;
                    a = this.Point1.X;
                    b = this.Point1.Y;
                    //MessageBox.Show("a={0}\n b={1} ", a, b);
                }
                private bool CheckMouse(Point mPos)
                {                double a = Point1.X - pb1.Width / 2;
                    double b = Point1.X + pb1.Width / 2;
                    double c = Point1.Y - pb1.Height / 2;
                    double d = Point1.Y + pb1.Height / 2;
                    if (mPos.X < a || mPos.X > b || mPos.Y < c || mPos.Y > d)
                        return false;
                    else
                        return true;
                }
                public void BeginInit()
                {            }            public void EndInit()
                {
                    if (this.DesignMode)
                        return;
                    if (this.m_Parent == null)
                        throw new Exception("没有设置承载连线的面板");
                    this.m_Parent.Paint += new PaintEventHandler(m_Parent_Paint);
                    this.m_Parent.MouseDown += new MouseEventHandler(m_Parent_MouseDown);
                    this.m_Parent.MouseUp += new MouseEventHandler(m_Parent_MouseUp);
                    this.m_Parent.MouseMove += new MouseEventHandler(m_Parent_MouseMove);
                    this.m_Parent.ContextMenuQuery1 += new ContextMenuQueryEventHandler(m_Parent_ContextMenuQuery);            }
            }
      

  2.   

    (同时在此感谢jointan无私的大力支持)
    重载的panel
    //////////////////////////////////////////////////////////////////////////
            //重载的Panel
            /// <summary>
            /// //////////////////////////////////////////////////////////////////
            /// </summary>
            public class GraphPanel : Panel
            {
                private ContextMenuStrip m_ContextMenuStrip=new ContextMenuStrip();            public ContextMenuStrip ContextMenuStrip1
                {
                    get { return m_ContextMenuStrip; }
                    set { m_ContextMenuStrip = value; }
                }
                
                public event ContextMenuQueryEventHandler ContextMenuQuery1;
                protected virtual void OnContextMenuQuery(MouseEventArgs e)
                {
                    try
                    {
                        ContextMenuQueryMenuEventArgs args = new ContextMenuQueryMenuEventArgs(e);
                        if (this.ContextMenuQuery1 != null)
                        {
                            this.ContextMenuQuery1(this, args);
                        }
                        if (args.Handle == false)
                        {
                            if (this.m_ContextMenuStrip != null)
                            this.m_ContextMenuStrip.Show(this, e.Location);
                        }
                    }
                    catch (Exception e1)
                    {
                        MessageBox.Show(e1.ToString());
                    }
                }
                protected override void OnMouseDown(MouseEventArgs e)
                {                this.Invalidate();
                    this.Update(); 
                    base.OnMouseDown(e);
                    if (e.Button == MouseButtons.Right)
                    {
                        
                        this.OnContextMenuQuery(e);
                       
                    }
                }
                
            }        public delegate void ContextMenuQueryEventHandler(object obj, ContextMenuQueryMenuEventArgs e);
            public class ContextMenuQueryMenuEventArgs : EventArgs
            {
                private MouseEventArgs m_MouseEventArgs;
                private bool m_Handle = false;
                public MouseEventArgs MouseEventArgs
                {
                    get { return m_MouseEventArgs; }            }
                public bool Handle
                {
                    get { return this.m_Handle; }
                    set { this.m_Handle = value; }
                }            public ContextMenuQueryMenuEventArgs(MouseEventArgs e)
                {
                    this.m_MouseEventArgs = e;
                    
                }
            }        private void Form1_Paint(object sender, PaintEventArgs e)
            {        }
            private void button1_Click(object sender, EventArgs e)
            {
                
                TiePaint paint1 = new TiePaint(this.components);
                ((System.ComponentModel.ISupportInitialize)(paint1)).BeginInit();
                paint1.Parent = graphpanel1;
                paint1.Point1 = new Point(100, 200);
                paint1.ContextMenu.Items.Add("图片1的上下文菜单");
                paint1.Parent.Invalidate();
                ((System.ComponentModel.ISupportInitialize)(paint1)).EndInit();
      
            }       
        }
      

  3.   

    如上面的代码所示:
        点击button1即可可以使用组件类TiePaint在重载的panel里绘制一个或者多个图标,此时的问题是:当绘制的多个图标的大小、形状、位置完全相同是,使用鼠标拖动其中一个图标,其它的图标一起移动,无论如何也分不开。
        
      

  4.   

    说真的这么看比较头痛。如果需要。你做个简单的例子,发我邮箱,帮你看看。[email protected]
      

  5.   

    private void m_Parent_MouseMove(object sender, MouseEventArgs e)
                {
                    if (!this.Selected)
                    {
                        this.m_OrgPoint = Point.Empty;
                        return;
                    }
                    if (this.m_OrgPoint == Point.Empty)
                    {
                        this.m_OrgPoint = e.Location;
                        return;
                    }
                    if (e.Button == MouseButtons.Left)
                    {
                       
                        if (this.Parent.ClientRectangle.Contains(e.Location))
                        {
                            this.m_Point.X += (e.Location.X - this.m_OrgPoint.X);
                            this.m_Point.Y += (e.Location.Y - this.m_OrgPoint.Y);
                            this.m_OrgPoint = e.Location;
                            this.m_Parent.Invalidate();
                            this.m_Parent.Update();
                        }
                        else
                        {
                            this.m_OrgPoint = Point.Empty;
                            this.Selected = false;
                        }
                    }这个函数有问题吧。你的mousemove事件里获取对象的时候让对象跟sender关联。这样就唯一确定了,点哪个就动哪个。
    sender用法:
    ((TiePaint)sender).Left
      

  6.   

    至whChina:
        1、不好意思,程序有点乱,让您费心了;
        2、关键问题如下:
            在TiePaint类中判断鼠标的位置,如果鼠标位于图标表是的矩形区域内时,当鼠标按下左键时,就使本图标处于被选中状态(使用状态变量m_Selected)private bool CheckMouse(Point mPos)//检查鼠标位置的函数,pb1为所绘制的图标,Point1是
                                       //图标的中心点
                {
                    double a = Point1.X - pb1.Width / 2;
                    double b = Point1.X + pb1.Width / 2;
                    double c = Point1.Y - pb1.Height / 2;
                    double d = Point1.Y + pb1.Height / 2;                //如果不再区域内返回false,在区域内返回true
                    if (mPos.X < a || mPos.X > b || mPos.Y < c || mPos.Y > d)//如不再区
                        return false;
                    else
                        return true;
                }    如果鼠标处于图标矩形范围内,那么就可以触发图标的MouseUp、MouseMove、MouseDown事件移动图标,但现在的问题是,如果多个(3个以上)图标的形状、大小、中心点位置全一样时,也就是几个图标完全重合,那么此时在重合区域点击鼠标试图移动图标时,所用重合的图标一起移动,就好像只存在一个图标。郁闷ing.........................
      

  7.   

    to:wuyazhe,让您见笑了,我没正经学过编程,可能是看了一些书,照书抄了一下罢了。
    程序已经收到,马上去试一试。
      

  8.   

    问题已经解决,感谢wuyazhe的慷慨赐教:)