none
控件拖动 RRS feed

答案

  • 示例代码:

    有这样一个场景,有AB两个客户总对界面摆放有着不同的喜好,一个喜欢查询条件输入区(被放在一个groupbox中)在界面的上半部分,输入区在下半部分(被放在另一个groupbox中),另一个用户则正好相反,所以我们在界面设计确认时今天A在时,我们听他的要求,改一次,明天A去开会了,B来确认,又让我们改回来,几次下来,觉得很痛苦,如果界面有区多的区域,比如说一个查询条件输入区、一个业务数据录入区、一个输出区,这种情况下,客户的喜好更是会让你左改右改,所以我们最后决定提供以GroupBox为单位的,运行时可拖拽上下位置的功能,让不同的客户根据自己的喜好去拖拽,我们后台自动保存设定就是了。

    场景描述很复杂,但代码实现却很简练:

    一个全权负责拖放管理的类实现:

    using System;
    using System.Windows.Forms;
    namespace Subindex
    {
    /// <summary>
    ///
    /// </summary>
    public class DragDropAgent//4 groupBox control in runtime dragDrop support, Written By Linnet 2006-4-6
    {
       private DragDropAgent()
       {
        //
        // TODO: 在此处添加构造函数逻辑
        //
       }

       /// <summary>
       /// 得到一个包含首层父控件的控件的对象名,如form1下groupbox1中的textbox1,将返回form1.textbox1
       /// </summary>
       /// <param name="sender">要获得对象名的控件实例</param>
       /// <returns></returns>
       public static string getFullName(Control sender)
       {
        string name=sender.Name;
        while (sender.Parent!=null)
         sender=sender.Parent;
        return sender.Name+"."+name;
       }

       /// <summary>
       /// 设置指定GroupBox控件的拖放操作,根据CanDrag和CanDrop决定拖出/放入的支持
       /// </summary>
       /// <param name="sender">要设置拖放特性的GroupBox对象</param>
       /// <param name="CanDrag">是否可以拖出</param>
       /// <param name="CanDrop">是否可以放入</param>
       public static void DragDropHook(GroupBox sender,bool CanDrag,bool CanDrop)
       {
        if (CanDrag) DragHook(sender);
        if (CanDrop) DropHook(sender);
        gutPosition(sender);
       }

       /// <summary>
       /// 设置指定GroupBox控件的拖放操作,同时支持拖出和放入
       /// </summary>
       /// <param name="sender">要设置拖放特性的GroupBox对象</param>
       public static void DragDropHook(GroupBox sender)
       {
        DragDropHook(sender,true,true);
       }

       private static void DragHook(GroupBox sender)
       {
        sender.MouseDown+=new MouseEventHandler(Do_Drag);
       }

       private static void DropHook(GroupBox sender)
       {
       
        sender.AllowDrop=true;
        sender.DragDrop+=new DragEventHandler(Drag_Drop);
        sender.DragEnter+=new DragEventHandler(Drag_Enter);
       }


       private static void Drag_Enter(object sender, System.Windows.Forms.DragEventArgs e)
       {
        if (e.Data.GetDataPresent(new GroupBox().GetType()))
         e.Effect = DragDropEffects.Move ;
       }

       private static void Do_Drag(object sender, MouseEventArgs e)
       {
        (sender as Control) .DoDragDrop(sender, DragDropEffects.Move);

       }

       private static void Drag_Drop(object sender, System.Windows.Forms.DragEventArgs e)
       {
        try
        {

         GroupBox self=sender as GroupBox;

         GroupBox ct= e.Data.GetData(self.GetType()) as GroupBox;

         if (self==ct) return;

         Control parent=self.Parent;

         int ord=parent.Controls.GetChildIndex(self);

         int ordself=self.Top>ct.Top?ord+1:ord-1;

         DockStyle dss=self.Dock;
         self.Dock=ct.Dock;;
         ct.Dock=dss;
         //     System.Drawing.Point dps=self.Location;
         //     self.Location=ct.Location;
         //     ct.Location=dps;

         if (ordself>ord)
         {
          setPosition(self,ordself);
          setPosition(ct,ord);
         }
         else
         {
          setPosition(ct,ord);
          setPosition(self,ordself);
         }

        }
        catch (Exception ee)
        {
         System.Windows.Forms.MessageBox.Show(ee.Message,"Error");

        }
       }

       private static void gutPosition(GroupBox sender)
       {

        string order=AppSettings.ReadSetting(getFullName(sender)+":Order");
        string dock=AppSettings.ReadSetting(getFullName(sender)+":Dock");
        try
        {
         int Position=int.Parse(order);
         sender.Parent.Controls.SetChildIndex(sender,Position);
         Position=int.Parse(dock);
         sender.Dock=(DockStyle)Position;
        }
        catch
        {

        }
       }

       private static void setPosition(GroupBox sender,int Position)
       {
        sender.Parent.Controls.SetChildIndex(sender,Position);

        AppSettings.WriteSetting(getFullName(sender)+":Order",Position.ToString());
        AppSettings.WriteSetting(getFullName(sender)+":Dock",((int)sender.Dock).ToString());


       }

     


    }
    }

     

     

    只要将所有groupBox的Dock属性设为同一方向后,只需要Form_Load时调用只需一句就可实现运行时拖放:

        DragDropAgent.DragDropHook(this.grpIndex);
        DragDropAgent.DragDropHook(this.grpWrap);//可拖动可放入,如果要设计成只可拖动或只可放入的请修改DragDropAgent类的那个实现方法的为public

    另外,上述类中使用了负责配置文件写入的AppSettings类,代码也一并给出:

    using System;
    using System.Xml;
    using System.Configuration;
    using System.Reflection;
    using System.IO;

    namespace Subindex
    {
    /// <summary>
    ///
    /// </summary>
    public class AppSettings
    {
       private static readonly string configFile;
       private AppSettings()
       {
        //
        // TODO: 在此处添加构造函数逻辑
        //
       }
       static AppSettings()
       {
        configFile=getConfigFilePath();
       }

    //   public static string ReadSetting(string key)
    //   {
    //    string s=null;
    //    try
    //    {
    //
    //     s= ConfigurationSettings.AppSettings[key];
    //    }
    //    catch (Exception e)
    //    {
    //     System.Windows.Forms.MessageBox.Show(e.Message);
    //    }
    //    return s;
    //   }

     

       public static string ReadSetting(string Key)
       {
        string Path="/configuration/appSettings/add";
        XmlDocument doc = loadConfigDocument();
        //if (doc.SelectSingleNode(Path) == null) return null;
        XmlElement elem = (XmlElement)doc.SelectSingleNode(string.Format(Path+"[@key='{0}']", Key));
        return elem==null?null:elem.GetAttribute("value");;
       }


       public static void WriteSetting(string Key, string Value)
       {
        XmlDocument doc = loadConfigDocument();

        if (doc.SelectSingleNode("//configuration") == null)
         doc.AppendChild(doc.CreateNode(XmlNodeType.Element,"configuration",""));

        XmlNode node = doc.SelectSingleNode("//appSettings");

        if (node == null)
        {
         node=doc.CreateNode(XmlNodeType.Element,"appSettings","");
         doc.SelectSingleNode("//configuration").AppendChild(node);
        
        }

        try
        {
         XmlElement elem = (XmlElement)node.SelectSingleNode(string.Format("//add[@key='{0}']", Key));

         if (elem != null)
         {
          elem.SetAttribute("value", Value);
         }
         else
         {
          elem = doc.CreateElement("add");
          elem.SetAttribute("key", Key);
          elem.SetAttribute("value", Value);
          node.AppendChild(elem);
         }
         doc.Save(configFile);
        }
        catch
        {
         throw;
        }
       }

       public static void RemoveSetting(string key)
       {
        XmlDocument doc = loadConfigDocument();

        XmlNode node = doc.SelectSingleNode("//appSettings");

        try
        {
         if (node == null)
          throw new InvalidOperationException("appSettings section not found in config file.");
         else
         {
          node.RemoveChild(node.SelectSingleNode(string.Format("//add[@key='{0}']", key)));
          doc.Save(configFile);
         }
        }
        catch (NullReferenceException e)
        {
         throw new Exception(string.Format("The key {0} does not exist.", key), e);
        }
       }

       private static XmlDocument loadConfigDocument()
       {
        XmlDocument doc = null;
        try
        {
         doc = new XmlDocument();
         doc.Load(configFile);
        }
        catch (Exception e)
        {
         System.Windows.Forms.MessageBox.Show(e.Message);
        }
        return doc;

       }

       public static string getConfigFilePath()
       {
        string configFile=Assembly.GetExecutingAssembly().Location + ".config";
        if (!File.Exists(configFile)) CreateFile(configFile);
        return configFile;
       }

       public static bool ConfigFileExist()
       {
        string configFile=Assembly.GetExecutingAssembly().Location + ".config";
        return File.Exists(configFile);
       }

       private static void CreateFile(string FileName)
       {
        XmlTextWriter writer = new XmlTextWriter(FileName,System.Text.Encoding.Default);
        writer.WriteStartElement("configuration");
        writer.WriteStartElement("appSettings");
        writer.WriteEndElement() ;
        writer.Flush();
        writer.Close();
       }
    }

    }

    来源:http://hi.baidu.com/huzhenqi/blog/item/fe9304d853479c3d32fa1c7f.html

    2010年8月3日 2:48
    版主