这是别人的程序的代码,帮我解释一下啊using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Reflection;
using AForge.Imaging.Filters;namespace IPLab
{
    /// <summary>
    /// FilterPreview window
    /// </summary>
    public class FilterPreview : System.Windows.Forms.Control
    {
        private Bitmap previewImage;
        private Bitmap image;
        private IFilter filter;
        private Pen blackPen = new Pen( Color.Black, 1 );
        private Cursor cursorHand;
        private Cursor cursorHandMove;        private int areaWidth, areaHeight;
        private int imageX, imageY;
        private bool tracking = false;        private int startTrackingX, startTrackingY;
        private int oldImageX, oldImageY;        // Image property
        [Browsable( false )]
        public Bitmap Image
        {
            get { return image; }
            set
            {
                image = value;                if ( value != null )
                {
                    // calculate size of preview area
                    areaWidth = Math.Min( ClientRectangle.Width - 2, image.Width );
                    areaHeight = Math.Min( ClientRectangle.Height - 2, image.Height );                    // calculate image position
                    imageX = ( image.Width - areaWidth ) >> 1;
                    imageY = ( image.Height - areaHeight ) >> 1;
                }                RefreshFilter( );
            }
        }
        // Filter property
        [Browsable( false )]
        public AForge.Imaging.Filters.IFilter Filter
        {
            set
            {
                filter = value;
                RefreshFilter( );
            }
        }        // Constructor
        public FilterPreview( )
        {
            InitializeComponent( );
            SetStyle( ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw |
                ControlStyles.DoubleBuffer | ControlStyles.UserPaint, true );
            // load cursors
            Assembly assembly = this.GetType( ).Assembly;
            cursorHand = new Cursor( assembly.GetManifestResourceStream( "IPLab.Resources.harrow.cur" ) );
            cursorHandMove = new Cursor( assembly.GetManifestResourceStream( "IPLab.Resources.hmove.cur" ) );
        }        // Dispose
        protected override void Dispose( bool disposing )
        {
            if ( disposing )
            {
                blackPen.Dispose( );                if ( previewImage != null )
                {
                    previewImage.Dispose( );
                    cursorHand.Dispose( );
                    cursorHandMove.Dispose( );
                }
            }
            base.Dispose( disposing );
        }        // Initialize control
        private void InitializeComponent( )
        {
            this.MouseUp += new System.Windows.Forms.MouseEventHandler( this.FilterPreview_MouseUp );
            this.MouseMove += new System.Windows.Forms.MouseEventHandler( this.FilterPreview_MouseMove );
            this.MouseDown += new System.Windows.Forms.MouseEventHandler( this.FilterPreview_MouseDown );
        }        // Paint control
        protected override void OnPaint( PaintEventArgs pe )
        {
            Graphics g = pe.Graphics;
            Rectangle rc = ClientRectangle;
            int width = rc.Width;
            int height = rc.Height;
            int x, y;            // calculate size of preview area
            if ( image != null )
            {
                width = areaWidth + 2;
                height = areaHeight + 2;
            }
            // calculate position of preview area
            x = ( rc.Width - width ) >> 1;
            y = ( rc.Height - height ) >> 1;            // draw rectangle
            g.DrawRectangle( blackPen, x, y, width - 1, height - 1 );            x++;
            y++;            if ( image != null )
            {
                if ( previewImage == null )
                {
                    // draw original image
                    g.DrawImage( image, new Rectangle( x, y, areaWidth, areaHeight ), imageX, imageY, areaWidth, areaHeight, GraphicsUnit.Pixel );
                }
                else
                {
                    // draw preview image
                    g.DrawImage( previewImage, x, y, areaWidth, areaHeight );
                }
            }            // Calling the base class OnPaint
            base.OnPaint( pe );
        }        // Refresh preview
        public void RefreshFilter( )
        {
            // release old image
            if ( previewImage != null )
            {
                previewImage.Dispose( );
                previewImage = null;
            }            if ( ( image != null ) && ( filter != null ) )
            {
                Bitmap tmp = image.Clone( new Rectangle( imageX, imageY, areaWidth, areaHeight ), image.PixelFormat );                try
                {
                    previewImage = filter.Apply( tmp );
                }
                catch ( Exception )
                {
                }                // release temp image
                tmp.Dispose( );
            }            // repaint
            Invalidate( );
        }        // On mouse move
        private void FilterPreview_MouseMove( object sender, System.Windows.Forms.MouseEventArgs e )
        {
            if ( image != null )
            {
                if ( !tracking )
                {
                    // calculate position of preview area
                    int x = ( ( ClientRectangle.Width - areaWidth - 2 )  >>1 ) + 1;
                    int y = ( ( ClientRectangle.Height - areaHeight - 2 )   >>1) + 1;                    // check mouse coordinates
                    if ( ( e.X >= x ) && ( e.Y >= y ) &&
                        ( e.X < x + areaWidth ) && ( e.Y < y + areaHeight ) )
                    {
                        Cursor = cursorHand;
                    }
                    else
                        Cursor = Cursors.Default;
                }
                else
                {
                    int dx = e.X - startTrackingX;
                    int dy = e.Y - startTrackingY;                    imageX = Math.Max( 0, Math.Min( image.Width - areaWidth, oldImageX - dx ) );
                    imageY = Math.Max( 0, Math.Min( image.Height - areaHeight, oldImageY - dy ) );                    Invalidate( );                    Cursor = cursorHandMove;
                }
            }
        }        // On mouse button down
        private void FilterPreview_MouseDown( object sender, System.Windows.Forms.MouseEventArgs e )
        {
            if ( ( image != null ) && ( e.Button == MouseButtons.Left ) )
            {
                // start tracking
                tracking = true;
                Capture = true;                startTrackingX = e.X;
                startTrackingY = e.Y;                oldImageX = imageX;
                oldImageY = imageY;                // release preview image
                if ( previewImage != null )
                {
                    previewImage.Dispose( );
                    previewImage = null;
                }
                // repaint
             //   Invalidate( );                // set cursor
                Cursor = cursorHandMove;
            }
        }        // On mouse button up
        private void FilterPreview_MouseUp( object sender, System.Windows.Forms.MouseEventArgs e )
        {
            if ( tracking )
            {
                // stop tracking
                tracking = false;
                Capture = false;                RefreshFilter( );                // set cursor
                Cursor = cursorHand;
            }
        }
    }
}

解决方案 »

  1.   

    FilterPreview_MouseDown的时候开始记录鼠标移动的开始位置,
    并设置标志
    tracking = true; FilterPreview_MouseDown的时候判断标志
    如果 tracking为true 计算要图片被移动到得新位置,并Invalidate( ); (重绘,会发消息调用OnPaint)
    如果tracking为false救根据鼠标位置在矩形内 则变换鼠标形状
    FilterPreview_MouseUp 设置标志位为false
    OnPaint根据计算得到的位置绘制图片
      

  2.   

    有一个简单的办法可以实现类似功能在窗体中放一个Panel,将Panel的AutoScroll属性设为true,
    然后将PictureBox放到Panel中,位置为(0,0)每次加载图片后,
    设置PictureBox的大小与图片的大小相同,即
    pictureBox.Size = pictureBox.Image.Size;
    这样如果图片过大的话,会出现滚动条。楼主如果要更好一点的,就是当图片小于Panel的高度或宽度时居中的话
    在加载图片后再计算一下PictureBox的位置就可以了。
      

  3.   

    你那个拖动效果其实是GDI重绘,看了你代码,也是这样的。
    g.DrawImage( image, new Rectangle( x, y, areaWidth, areaHeight ), imageX, imageY, areaWidth, areaHeight, GraphicsUnit.Pixel ); 
    大概思路是这样的,PictureBox是固定的,然后定义一块画布,画布的大小跟PictureBox一样,但是画布每次描绘的图像不一样,即是根据原图和坐标重新绘画出来的,就是上一段代码。当你发生鼠标或者键盘事件时,更改绘画的坐标,这样就实现“拖动”效果了。