FlexiblePanel.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Drawing;
  5. using System.Data;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using System.Windows.Forms;
  10. using System.Xml;
  11. using System.IO;
  12. namespace Y.Skin.YoPanel
  13. {
  14. public partial class FlexiblePanel : Panel
  15. {
  16. //Color HighlightColor = ColorTranslator.FromHtml("#78c4ec");
  17. Color HighlightColor = Color.Transparent;
  18. /// <summary>
  19. /// 光标状态
  20. /// </summary>
  21. private enum EnumMousePointPosition
  22. {
  23. MouseSizeNone = 0, //'无
  24. MouseSizeRight = 1, //'拉伸右边框
  25. MouseSizeLeft = 2, //'拉伸左边框
  26. MouseSizeBottom = 3, //'拉伸下边框
  27. MouseSizeTop = 4, //'拉伸上边框
  28. MouseSizeTopLeft = 5, //'拉伸左上角
  29. MouseSizeTopRight = 6, //'拉伸右上角
  30. MouseSizeBottomLeft = 7, //'拉伸左下角
  31. MouseSizeBottomRight = 8, //'拉伸右下角
  32. MouseDrag = 9 // '鼠标拖动
  33. }
  34. #region 属性
  35. private static string xmlDocPath = AppDomain.CurrentDomain.BaseDirectory + @"\Layout.xml";
  36. private XmlDocument doc;
  37. private const int Band = 5;
  38. private const int MinWidth = 10;
  39. private const int MinHeight = 10;
  40. private EnumMousePointPosition m_MousePointPosition;
  41. private Point p, p1;
  42. #endregion
  43. public FlexiblePanel()
  44. {
  45. SetStyle(ControlStyles.UserPaint, true);
  46. SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.
  47. SetStyle(ControlStyles.DoubleBuffer, true); // 双缓冲
  48. InitializeComponent();
  49. }
  50. #region 改变控件大小和移动位置用到的方法
  51. private void MyMouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
  52. {
  53. p.X = e.X;
  54. p.Y = e.Y;
  55. p1.X = e.X;
  56. p1.Y = e.Y;
  57. }
  58. /// <summary>
  59. /// 鼠标离开事件需要改进
  60. /// </summary>
  61. /// <param name="sender"></param>
  62. /// <param name="e"></param>
  63. private void MyMouseLeave(object sender, EventArgs e)
  64. {
  65. if (doc == null)
  66. doc = new XmlDocument();
  67. Control s = (Control)sender;
  68. XmlNodeList nodes = doc.GetElementsByTagName(s.Name);
  69. XmlElement xn;
  70. if (nodes.Count != 1)
  71. {
  72. xn = doc.CreateElement(s.Name);
  73. }
  74. else
  75. {
  76. xn = (XmlElement)doc.GetElementsByTagName(s.Name)[0];
  77. }
  78. xn.SetAttribute("Top", s.Top.ToString());
  79. xn.SetAttribute("Left", s.Left.ToString());
  80. xn.SetAttribute("Width", s.Width.ToString());
  81. xn.SetAttribute("Height", s.Height.ToString());
  82. XmlNodeList xnl = doc.GetElementsByTagName(this.Name);
  83. XmlElement xnp;
  84. if (xnl.Count < 1)
  85. {
  86. xnp = doc.CreateElement(this.Name);
  87. }
  88. else
  89. {
  90. xnp = (XmlElement)xnl[0];
  91. }
  92. xnp.AppendChild(xn);
  93. doc.AppendChild(xnp);
  94. doc.Save(xmlDocPath);
  95. m_MousePointPosition = EnumMousePointPosition.MouseSizeNone;
  96. this.Cursor = Cursors.Arrow;
  97. //((Control)sender).BackColor = Color.Transparent;
  98. }
  99. private EnumMousePointPosition MousePointPosition(Size size, System.Windows.Forms.MouseEventArgs e)
  100. {
  101. if ((e.X >= -1 * Band) | (e.X <= size.Width) | (e.Y >= -1 * Band) | (e.Y <= size.Height))
  102. {
  103. if (e.X < Band)
  104. {
  105. if (e.Y < Band) { return EnumMousePointPosition.MouseSizeTopLeft; }
  106. else
  107. {
  108. if (e.Y > -1 * Band + size.Height)
  109. { return EnumMousePointPosition.MouseSizeBottomLeft; }
  110. else
  111. { return EnumMousePointPosition.MouseSizeLeft; }
  112. }
  113. }
  114. else
  115. {
  116. if (e.X > -1 * Band + size.Width)
  117. {
  118. if (e.Y < Band)
  119. { return EnumMousePointPosition.MouseSizeTopRight; }
  120. else
  121. {
  122. if (e.Y > -1 * Band + size.Height)
  123. { return EnumMousePointPosition.MouseSizeBottomRight; }
  124. else
  125. { return EnumMousePointPosition.MouseSizeRight; }
  126. }
  127. }
  128. else
  129. {
  130. if (e.Y < Band)
  131. { return EnumMousePointPosition.MouseSizeTop; }
  132. else
  133. {
  134. if (e.Y > -1 * Band + size.Height)
  135. { return EnumMousePointPosition.MouseSizeBottom; }
  136. else
  137. { return EnumMousePointPosition.MouseDrag; }
  138. }
  139. }
  140. }
  141. }
  142. else
  143. { return EnumMousePointPosition.MouseSizeNone; }
  144. }
  145. private void MyMouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
  146. {
  147. Control lCtrl = (sender as Control);
  148. if (e.Button == MouseButtons.Left)
  149. {
  150. switch (m_MousePointPosition)
  151. {
  152. case EnumMousePointPosition.MouseDrag:
  153. lCtrl.Left = lCtrl.Left + e.X - p.X;
  154. lCtrl.Top = lCtrl.Top + e.Y - p.Y;
  155. break;
  156. case EnumMousePointPosition.MouseSizeBottom:
  157. lCtrl.Height = lCtrl.Height + e.Y - p1.Y;
  158. p1.X = e.X;
  159. p1.Y = e.Y; //'记录光标拖动的当前点
  160. break;
  161. case EnumMousePointPosition.MouseSizeBottomRight:
  162. lCtrl.Width = lCtrl.Width + e.X - p1.X;
  163. lCtrl.Height = lCtrl.Height + e.Y - p1.Y;
  164. p1.X = e.X;
  165. p1.Y = e.Y; //'记录光标拖动的当前点
  166. break;
  167. case EnumMousePointPosition.MouseSizeRight:
  168. lCtrl.Width = lCtrl.Width + e.X - p1.X;
  169. // lCtrl.Height = lCtrl.Height + e.Y - p1.Y;
  170. p1.X = e.X;
  171. p1.Y = e.Y; //'记录光标拖动的当前点
  172. break;
  173. case EnumMousePointPosition.MouseSizeTop:
  174. lCtrl.Top = lCtrl.Top + (e.Y - p.Y);
  175. lCtrl.Height = lCtrl.Height - (e.Y - p.Y);
  176. break;
  177. case EnumMousePointPosition.MouseSizeLeft:
  178. lCtrl.Left = lCtrl.Left + e.X - p.X;
  179. lCtrl.Width = lCtrl.Width - (e.X - p.X);
  180. break;
  181. case EnumMousePointPosition.MouseSizeBottomLeft:
  182. lCtrl.Left = lCtrl.Left + e.X - p.X;
  183. lCtrl.Width = lCtrl.Width - (e.X - p.X);
  184. lCtrl.Height = lCtrl.Height + e.Y - p1.Y;
  185. p1.X = e.X;
  186. p1.Y = e.Y; //'记录光标拖动的当前点
  187. break;
  188. case EnumMousePointPosition.MouseSizeTopRight:
  189. lCtrl.Top = lCtrl.Top + (e.Y - p.Y);
  190. lCtrl.Width = lCtrl.Width + (e.X - p1.X);
  191. lCtrl.Height = lCtrl.Height - (e.Y - p.Y);
  192. p1.X = e.X;
  193. p1.Y = e.Y; //'记录光标拖动的当前点
  194. break;
  195. case EnumMousePointPosition.MouseSizeTopLeft:
  196. lCtrl.Left = lCtrl.Left + e.X - p.X;
  197. lCtrl.Top = lCtrl.Top + (e.Y - p.Y);
  198. lCtrl.Width = lCtrl.Width - (e.X - p.X);
  199. lCtrl.Height = lCtrl.Height - (e.Y - p.Y);
  200. break;
  201. default:
  202. break;
  203. }
  204. if (lCtrl.Width < MinWidth) lCtrl.Width = MinWidth;
  205. if (lCtrl.Height < MinHeight) lCtrl.Height = MinHeight;
  206. }
  207. else
  208. {
  209. m_MousePointPosition = MousePointPosition(lCtrl.Size, e); //'判断光标的位置状态
  210. switch (m_MousePointPosition) //'改变光标
  211. {
  212. case EnumMousePointPosition.MouseSizeNone:
  213. this.Cursor = Cursors.Arrow; //'箭头
  214. break;
  215. case EnumMousePointPosition.MouseDrag:
  216. this.Cursor = Cursors.SizeAll; //'四方向
  217. //((Control)sender).BackColor = HighlightColor;
  218. break;
  219. case EnumMousePointPosition.MouseSizeBottom:
  220. this.Cursor = Cursors.SizeNS; //'南北
  221. break;
  222. case EnumMousePointPosition.MouseSizeTop:
  223. this.Cursor = Cursors.SizeNS; //'南北
  224. break;
  225. case EnumMousePointPosition.MouseSizeLeft:
  226. this.Cursor = Cursors.SizeWE; //'东西
  227. break;
  228. case EnumMousePointPosition.MouseSizeRight:
  229. this.Cursor = Cursors.SizeWE; //'东西
  230. break;
  231. case EnumMousePointPosition.MouseSizeBottomLeft:
  232. this.Cursor = Cursors.SizeNESW; //'东北到南西
  233. break;
  234. case EnumMousePointPosition.MouseSizeBottomRight:
  235. this.Cursor = Cursors.SizeNWSE; //'东南到西北
  236. break;
  237. case EnumMousePointPosition.MouseSizeTopLeft:
  238. this.Cursor = Cursors.SizeNWSE; //'东南到西北
  239. break;
  240. case EnumMousePointPosition.MouseSizeTopRight:
  241. this.Cursor = Cursors.SizeNESW; //'东北到南西
  242. break;
  243. default:
  244. break;
  245. }
  246. }
  247. }
  248. #endregion
  249. #region 初始化鼠标事件委托和控件大小和移动
  250. private void initProperty()
  251. {
  252. for (int i = 0; i < this.Controls.Count; i++)
  253. {
  254. this.Controls[i].MouseDown += new System.Windows.Forms.MouseEventHandler(MyMouseDown);
  255. this.Controls[i].MouseLeave += new System.EventHandler(MyMouseLeave);
  256. this.Controls[i].MouseMove += new System.Windows.Forms.MouseEventHandler(MyMouseMove);
  257. }
  258. }
  259. private void initStyle()
  260. {
  261. Control s;
  262. for (int i = 0; i < this.Controls.Count; i++)
  263. {
  264. s = this.Controls[i];
  265. XmlNodeList nodes = doc.GetElementsByTagName(s.Name);
  266. if (nodes.Count == 1)
  267. {
  268. XmlAttributeCollection xac = nodes[0].Attributes;
  269. foreach (XmlAttribute xa in xac)
  270. {
  271. if (xa.Value == "")
  272. continue;
  273. switch (xa.Name)
  274. {
  275. case "Top":
  276. var Top = Convert.ToInt32(xa.Value);
  277. //if (Top > 0 && Top < this.Height - s.Height)
  278. s.Top = Top;
  279. break;
  280. case "Left":
  281. var Left = Convert.ToInt32(xa.Value);
  282. //if (Left > 0 && Left < this.Width - s.Width)
  283. s.Left = Left;
  284. break;
  285. case "Width":
  286. s.Width = Convert.ToInt32(xa.Value);
  287. break;
  288. case "Height":
  289. s.Height = Convert.ToInt32(xa.Value);
  290. break;
  291. default:
  292. break;
  293. }
  294. }
  295. }
  296. }
  297. }
  298. #endregion
  299. /// <summary>
  300. /// 用于实现容器内控件移动和改变大小的方法
  301. /// </summary>
  302. /// <param name="XmlDoc">用于保存控件的属性的XML文档</param>
  303. public void InitMouseAndContolStyle()
  304. {
  305. initProperty();
  306. if (File.Exists(xmlDocPath))
  307. {
  308. doc = new XmlDocument();
  309. doc.Load(xmlDocPath);
  310. initStyle();
  311. }
  312. }
  313. }
  314. }