winform在程序运行中,鼠标选中控件,控件呈选中状态,并能拖动拖动鼠标改变控件大小和位置,如从工具箱中创建控件一样的效果,最好提供代码

解决方案 »

  1.   

    用如下的代码可以生成一个可以移动并调整大小的UserControl,可以把代码添加到一个Window应用程序中,编译项目,然后打开一个Form设计窗体向其添加MoveableControl类型的控件,运行程序可以用鼠标来调整这个控件了,任何一个窗口类型的类都可以做为这个类的基类,比如Button,Panel,PictureBox, ListBox等等,都可以:
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows.Forms;
    using System.Drawing;namespace someTest
    {
    class MoveableControl:UserControl
    {
    internal static int WM_NCHITTEST = 0x84; //移动鼠标,按住或释放鼠标时发生的系统消息
    internal static int WM_NCACTIVATE = 0x86;//窗体的激活状态发生改变的消息 internal static IntPtr HTCLIENT = (IntPtr)0x1;//工作区
    internal static IntPtr HTSYSMENU = (IntPtr)3;//系统菜单
    internal static IntPtr HTCAPTION = (IntPtr)0x2; //标题栏 internal static IntPtr HTLEFT = (IntPtr)10;//向左
    internal static IntPtr HTRIGHT = (IntPtr)11;//向右
    internal static IntPtr HTTOP = (IntPtr)12;//向上
    internal static IntPtr HTTOPLEFT = (IntPtr)13;//向左上
    internal static IntPtr HTTOPRIGHT = (IntPtr)14;//向右上
    internal static IntPtr HTBOTTOM = (IntPtr)15;//向下
    internal static IntPtr HTBOTTOMLEFT = (IntPtr)16;//向左下
    internal static IntPtr HTBOTTOMRIGHT = (IntPtr)17;//向右下 private int m_BorderWidth = 4;
    private bool m_Sizeable = true;
    protected override void WndProc(ref Message m)
    {
    if (m.Msg == WM_NCHITTEST)
    {
    base.WndProc(ref m);
    if (DesignMode)
    {
    return;
    }
    if (m.Result == HTCLIENT)
    {
    m.HWnd = this.Handle; System.Drawing.Rectangle rect = this.RectangleToScreen(this.ClientRectangle);
    Point C_Pos = Cursor.Position;
    if ((C_Pos.X <= rect.Left + m_BorderWidth) && (C_Pos.Y <= rect.Top + m_BorderWidth) && this.m_Sizeable)
    m.Result = HTTOPLEFT;//左上
    else if ((C_Pos.X >= rect.Left + rect.Width - m_BorderWidth) && (C_Pos.Y <= rect.Top + m_BorderWidth) && this.m_Sizeable)
    m.Result = HTTOPRIGHT;//右上
    else if ((C_Pos.X <= rect.Left + m_BorderWidth) && (C_Pos.Y >= rect.Top + rect.Height - m_BorderWidth) && this.m_Sizeable)
    m.Result = HTBOTTOMLEFT;//左下
    else if ((C_Pos.X >= rect.Left + rect.Width - m_BorderWidth) && (C_Pos.Y >= rect.Top + rect.Height - m_BorderWidth) && this.m_Sizeable)
    m.Result = HTBOTTOMRIGHT;//右下
    else if ((C_Pos.X <= rect.Left + m_BorderWidth - 1) && this.m_Sizeable)
    m.Result = HTLEFT;//左
    else if ((C_Pos.X >= rect.Left + rect.Width - m_BorderWidth) && this.m_Sizeable)
    m.Result = HTRIGHT;//右
    else if ((C_Pos.Y <= rect.Top + m_BorderWidth - 1) && this.m_Sizeable)
    m.Result = HTTOP;//上
    else if ((C_Pos.Y >= rect.Top + rect.Height - m_BorderWidth) && this.m_Sizeable)
    m.Result = HTBOTTOM;//下
    else
    {
    m.Result = HTCAPTION;//模拟标题栏,移动或双击可以最大或最小化窗体
    }
    }
    return;
    }
    base.WndProc(ref m);
    }
    }
    }
      

  2.   

    可以把usercontrole换成button或者其他的.不过还有个问题.控件的其他事件都没了
      

  3.   

    可以把usercontrole换成button或者其他的
    这个当然是可以的,
    可是我要用到好几种组件,那不是每个组件都要继承类
    这样比较麻烦呀。
    有没有办法从窗体考虑,我按下CTRL可以选择多个进行拉动,这个要如何考虑
    谢谢
      

  4.   

    听说可以通过IDE自带的功能就可以实现,
    但是不知道如何实现
    谁知道告诉一下,谢谢
      

  5.   

    自己UP一下winform在程序运行中,鼠标选中控件,控件呈选中状态这个还没有实现,就是显示那6个点,谢谢
      

  6.   

    楼主“就是显示那6个点”
    这6个点可不好画啊,(多数应该为8个点)
    这可是画到控件外面去的。如果你不必要一定要是真正的控件,你可以通过画图来实现。
    在需要的时候你再跟据画图所得到的数据再生成所需的控件。你可以参考如下的方法来画图:
    ControlPaint类:.NET Framework 类库  
    ControlPaint 类  
    提供用于绘制常用 Windows 控件及其元素的方法。无法继承此类。 命名空间:System.Windows.Forms
    程序集:System.Windows.Forms(在 system.windows.forms.dll 中)备注使用 ControlPaint 类中包含的方法可以绘制自己的控件或控件的元素。如果对于您自已的控件,将 UserPaint 位设置为 true,则可以控制这些控件的绘制。可通过调用 GetStyle 或 SetStyle 方法来获取或设置样式位。对任何控件均可设置多个样式位。可使用按位运算组合 ControlStyles 枚举成员。
    示例
    下面的代码示例使用一个 ControlPaint 构造函数绘制一个平面 Button 控件。using System;
    using System.Drawing;
    using System.Windows.Forms;public class Form1 : Form
    {
          private Button button1 = new Button();
          private Button button2 = new Button();
        [STAThread]
        static void Main() 
        {
            Application.Run(new Form1());
        }
        public Form1(){
            this.button2.Location = new Point(0, button1.Height + 10);
            this.Click += new EventHandler(this.button2_Click);
            this.Controls.Add(this.button1);
            this.Controls.Add(this.button2);
        }    private void button2_Click(object sender, System.EventArgs e)
        {
            // Draws a flat button on button1.
            ControlPaint.DrawButton(
            System.Drawing.Graphics.FromHwnd(button1.Handle),0,0,button1.Width,button1.Height,
                    ButtonState.Flat);
        }
    }
      

  7.   

    在ControlPaint 类中提供了大部分Windows标准控件的画法,及一般常见的画图。
    像DrawGrabHandle 这个方法就是画出控件被选中的状态的:DrawGrabHandle  在指定的边界内、指定的图形表面上,按样式绘制处于指定状态的标准的选择抓取柄标志符号。