Rebar.cs
上传用户:nnpulika
上传日期:2013-02-15
资源大小:597k
文件大小:19k
源码类别:

状态条

开发平台:

C#

  1. using System;
  2. using System.Windows.Forms;
  3. using System.Drawing;
  4. using System.Collections;
  5. using System.Diagnostics;
  6. using System.Runtime.InteropServices;
  7. using System.ComponentModel;
  8. using UtilityLibrary.Collections;
  9. using UtilityLibrary.Win32;
  10. using UtilityLibrary.General;
  11. using UtilityLibrary.Designers;
  12. namespace UtilityLibrary.CommandBars
  13. {
  14. /// <summary>
  15. /// Summary description for Rebar.
  16. /// </summary>
  17. [ToolboxBitmap(typeof(UtilityLibrary.CommandBars.ReBar), 
  18.  "UtilityLibrary.CommandBars.ReBar.bmp")]
  19. [Designer(typeof(UtilityLibrary.Designers.ReBarDesigner))]
  20. public class ReBar : Control, IMessageFilter
  21. {
  22. #region Class Variables
  23. RebarBandCollection bands = null;
  24. static bool needsColorUpdate = false;
  25. bool bGotIsCommonCtrl6 = false;
  26. bool isCommonCtrl6 = false;
  27. const int MINIMUM_HEIGHT = 30;
  28. // Designer Support
  29. ToolBarEx placeHolderToolBar = null;
  30. bool placeHolderAdded = false;
  31. ReBarDesigner rebarDesigner = null;
  32. bool addPlaceHolderToolBar = false;
  33. bool designerInTransaction = false;
  34. #endregion
  35. #region Constructors
  36. public ReBar()
  37. {
  38. Initialize();
  39. }
  40. void Initialize()
  41. {
  42. SetStyle(ControlStyles.UserPaint, false);
  43. TabStop = false;
  44. Dock = DockStyle.Top;
  45. bands = new RebarBandCollection(this);
  46. bands.Changed += new EventHandler(Bands_Changed);
  47. addPlaceHolderToolBar = true;
  48. }
  49. #endregion
  50. #region Overrides
  51. protected override void OnMouseMove(MouseEventArgs e)
  52. {
  53. base.OnMouseMove(e);
  54. if ( Capture )
  55. return;
  56. bool hit = HitGripper(e);
  57. if ( hit )
  58. {
  59. if ( ShowMoveCursor(e) )
  60. Cursor.Current = Cursors.SizeAll;
  61. else
  62. Cursor.Current = Cursors.SizeWE;
  63. }
  64. else
  65. Cursor.Current = Cursors.Default;
  66. }
  67. protected override void OnMouseDown(MouseEventArgs e)
  68. {
  69. base.OnMouseDown(e);
  70. bool hit = HitGripper(e);
  71. if ( hit ) 
  72. {
  73. Capture = true;
  74. if ( ShowMoveCursor(e) )
  75. Cursor.Current = Cursors.SizeAll;
  76. else
  77. Cursor.Current = Cursors.VSplit;
  78. }
  79. else
  80. Cursor.Current = Cursors.Default;
  81. }
  82. protected override void OnMouseUp(MouseEventArgs e)
  83. {
  84. base.OnMouseUp(e);
  85. bool hit = HitGripper(e);
  86. Capture = false;
  87. if ( hit )
  88. {
  89. if ( ShowMoveCursor(e) )
  90. Cursor.Current = Cursors.SizeAll;
  91. else
  92. Cursor.Current = Cursors.SizeWE;
  93. }
  94. else
  95. Cursor.Current = Cursors.Default;
  96. }
  97. protected override void Dispose(bool disposing)
  98. {
  99. if ( disposing )
  100. bands.Changed -= new EventHandler(Bands_Changed);
  101. }
  102. protected override void OnHandleCreated(EventArgs e)
  103. {
  104. base.OnHandleCreated(e);
  105. RealizeBands();
  106. }
  107. protected override void WndProc(ref Message m) 
  108. {
  109. base.WndProc(ref m);
  110. switch (m.Msg)
  111. {
  112. case (int)Msg.WM_PAINT:
  113. PaintBackground();
  114. break;
  115. case (int)Msg.WM_NOTIFY:
  116. case (int)((int)Msg.WM_NOTIFY + (int)Msg.WM_REFLECT):
  117. {
  118. NMHDR note = (NMHDR)m.GetLParam(typeof(NMHDR));
  119. switch (note.code)
  120. {
  121. case (int)RebarNotifications.RBN_HEIGHTCHANGE:
  122. UpdateSize();
  123. break;
  124. case (int)RebarNotifications.RBN_CHEVRONPUSHED:
  125. NotifyChevronPushed(ref m);
  126. break;
  127. case (int)RebarNotifications.RBN_CHILDSIZE:
  128. NotifyChildSize();
  129. break;
  130. case (int)NotificationMessages.NM_NCHITTEST:
  131. break;
  132. }
  133. }
  134. break;
  135. }
  136. }
  137. protected override void OnParentChanged(EventArgs e)
  138. {
  139. if (Parent != null)
  140. Application.AddMessageFilter(this);
  141. else
  142. Application.RemoveMessageFilter(this);
  143. }
  144. protected override Size DefaultSize
  145. {
  146. get 
  147. return new Size(100, 44); 
  148. }
  149. }
  150. protected override void CreateHandle() 
  151. {
  152. if (!RecreatingHandle)
  153. {
  154. INITCOMMONCONTROLSEX icex = new INITCOMMONCONTROLSEX();
  155. icex.dwSize = Marshal.SizeOf(typeof(INITCOMMONCONTROLSEX));
  156. icex.dwICC = (CommonControlInitFlags.ICC_BAR_CLASSES | CommonControlInitFlags.ICC_COOL_CLASSES);
  157. bool  fail = WindowsAPI.InitCommonControlsEx(icex);
  158. }
  159. base.CreateHandle();
  160. }
  161. protected override CreateParams CreateParams
  162. {
  163. get
  164. {
  165. CreateParams createParams = base.CreateParams;
  166. createParams.ClassName = WindowsAPI.REBARCLASSNAME;
  167. createParams.Style = (int)(WindowStyles.WS_CHILD | WindowStyles.WS_VISIBLE
  168. | WindowStyles.WS_CLIPCHILDREN | WindowStyles.WS_CLIPSIBLINGS);
  169. createParams.Style |= (int)(CommonControlStyles.CCS_NODIVIDER | CommonControlStyles.CCS_NOPARENTALIGN);
  170. createParams.Style |= (int)(RebarStyles.RBS_VARHEIGHT | RebarStyles.RBS_AUTOSIZE);
  171. return createParams;
  172. }
  173. }
  174. public override bool PreProcessMessage(ref Message msg)
  175. {
  176. foreach (Control band in bands)
  177. {
  178. if (band.PreProcessMessage(ref msg))
  179. return true;
  180. }
  181. return false;
  182. }
  183. #endregion
  184. #region Properties
  185. [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
  186. public RebarBandCollection Bands
  187. {
  188. get { return bands; }
  189. }
  190. internal bool PlaceHolderAdded
  191. {
  192. get { return placeHolderAdded; }
  193. }
  194. internal bool AddPlaceHolderToolBar
  195. {
  196. set { addPlaceHolderToolBar = value; }
  197. get { return addPlaceHolderToolBar; }
  198. }
  199. internal ToolBarEx PlaceHolderToolBar
  200. {
  201. get { return placeHolderToolBar; }
  202. }
  203. internal ReBarDesigner RebarDesigner
  204. {
  205. set { rebarDesigner = value; }
  206. get { return rebarDesigner; }
  207. }
  208. internal bool DesignerInTransaction
  209. {
  210. set { designerInTransaction = value; }
  211. get { return designerInTransaction; }
  212. }
  213.         
  214. #endregion
  215. #region Methods
  216. public void UpdateBackgroundColor()
  217. {
  218. for ( int i = 0; i < bands.Count; i++ )
  219. {
  220. // Update Rebar band information
  221. // This make sure that the background color and foreground color
  222. // of the bands are set to the new system colors
  223. UpdateBand(i);
  224. ToolBarEx toolBar = (ToolBarEx)bands[i];
  225. toolBar.Invalidate();
  226. }
  227. Invalidate();
  228. }
  229. static public void UpdateBandsColors(object sender, EventArgs e)
  230. {
  231. needsColorUpdate = true;
  232. }
  233. #endregion
  234. #region Implementation
  235. private bool IsCommonCtrl6()
  236. {
  237. // Cache this value for efficenty
  238. if ( bGotIsCommonCtrl6 == false )
  239. {
  240. isCommonCtrl6 = WindowsAPI.IsCommonCtrl6();
  241. }
  242. return isCommonCtrl6;
  243. }
  244. internal void PassMsg(ref Message m)
  245. {
  246. WndProc(ref m);
  247. }
  248. internal void AddPlaceHolder()
  249. {
  250. placeHolderAdded = true;
  251. // Add place holder toolBar for designer support
  252. if ( placeHolderToolBar == null )
  253. {
  254. placeHolderToolBar = new ToolBarEx();
  255. placeHolderToolBar.parentRebar = this;
  256. }
  257. REBARBANDINFO bandInfo = GetBandInfo(0, placeHolderToolBar);
  258. int result = WindowsAPI.SendMessage(Handle, RebarMessages.RB_INSERTBANDW, 0, ref bandInfo);
  259. }
  260. internal void RemovePlaceHolder()
  261. {
  262. placeHolderAdded = false;
  263. REBARBANDINFO bandInfo = GetBandInfo(0, placeHolderToolBar);
  264. int result = WindowsAPI.SendMessage(Handle, (int)RebarMessages.RB_DELETEBAND, 0, 0);
  265. }
  266. internal void RemoveBand(int index)
  267. {
  268.             // index is base on the Band collection
  269. // but we need the actual index used in the native Rebar control
  270. int actualIndex = GetBandActualIndex(index);
  271. int result = WindowsAPI.SendMessage(Handle, (int)RebarMessages.RB_DELETEBAND, actualIndex, 0);
  272. }
  273. private void PaintBackground()
  274. {
  275. // This is for the very first time the ToolBarEx place holder is added
  276. if ( bands.Count == 0  &&  addPlaceHolderToolBar == true)
  277. {
  278.                 addPlaceHolderToolBar = false;
  279. AddPlaceHolder();
  280. }
  281. if ( needsColorUpdate)
  282. {
  283. needsColorUpdate = false;
  284. for ( int i = 0; i < bands.Count; i++ )
  285. {
  286. // Update toolbar specific information
  287. // This update is to guarantee that the toolbar can resize
  288. // the buttons appropiately in case the SystemMenuFont was
  289. // changed along with the system colors
  290. ToolBarEx toolBar = (ToolBarEx)bands[i];
  291. toolBar.UpdateToolBarItems();
  292. }
  293. for ( int i = 0; i < bands.Count; i++ )
  294. {
  295. // Update Rebar band information
  296. // This make sure that the background color and foreground color
  297. // of the bands are set to the new system colors
  298. UpdateBand(i);
  299. }
  300. }
  301. // We don't need to paint the gripper if we are going
  302. // to let the operating system do the painting
  303. if ( IsCommonCtrl6())
  304. return;
  305. Control c = null;
  306. Rectangle rc;
  307. for ( int i = 0; i < bands.Count; i++ )
  308. {
  309. Graphics g = CreateGraphics();
  310. c = bands[i];
  311. RectangleF rf = g.ClipBounds;
  312. rc = c.Bounds;
  313. if ( rf.Contains(rc) )
  314. {
  315. ToolBarEx toolBar = (ToolBarEx)bands[i];
  316. if ( toolBar.BarType == BarType.MenuBar ) 
  317. {
  318. // The menu bar height is smaller that the other toolbars
  319. // and if the menubar is in the same row with a toolbar that is bigger in height
  320. // the toolbar gripper will not be painted correctly if we use the actual height
  321. // of the menubar. Instead ajust the rectangle to compensate for the actual height
  322. // of the band
  323. Rectangle menuRect = GetBandRect(i);
  324. int offset = (menuRect.Height - rc.Height)/2-1;
  325. rc = new Rectangle(rc.Left, rc.Top-offset, menuRect.Width, menuRect.Height-2);
  326. }
  327. DrawGripper(g, rc, c.BackColor);
  328. }
  329. g.Dispose();
  330. }
  331. }
  332. private void DrawGripper(Graphics g, Rectangle bounds, Color backColor)
  333. {
  334. bounds.X = bounds.Left - 7;
  335. bounds.Width = 7;
  336. using ( Brush b = new SolidBrush(backColor) )
  337. {
  338. g.FillRectangle(b, bounds);
  339. }
  340. int nHeight = bounds.Height;
  341. for ( int i = 2; i < nHeight-1; i++) 
  342. {
  343. if ( ColorUtil.UsingCustomColor )
  344. {
  345. using ( Pen p = new Pen(ColorUtil.VSNetBorderColor, 1))
  346. {
  347. g.DrawLine(p, bounds.Left, bounds.Top+i, bounds.Left+3, bounds.Top+i);
  348. }
  349. }
  350. else 
  351. {
  352. using ( Pen p = new Pen(SystemColors.ControlDark, 1))
  353. {
  354. g.DrawLine(p, bounds.Left, bounds.Top+i, bounds.Left+3, bounds.Top+i);
  355. }
  356. }
  357. i++;
  358. }
  359. }
  360. protected bool HitGripper(MouseEventArgs e)
  361. {
  362. // Find out if we hit the gripper
  363. Point mousePoint = new Point(e.X, e.Y);
  364. Control c = null;
  365. Rectangle bounds;
  366. for ( int i = 0; i < bands.Count; i++ )
  367. {
  368. c = bands[i];
  369. bounds = c.Bounds;
  370. // adjust to gripper area
  371. bounds.X = bounds.Left - 7;
  372. bounds.Width = 7;
  373. if ( bounds.Contains(mousePoint) )
  374. return true;
  375. }
  376. return false;
  377. }
  378. private bool ShowMoveCursor(MouseEventArgs e)
  379. {
  380. // Even though we can actually move the toolbars around always
  381. // sometimes it is more intuive to show the "Move" cursor depending
  382. // how many bars are in the same row that always showing the resize cursor
  383. Point mousePoint = new Point(e.X, e.Y);
  384. Control c = null;
  385. Rectangle bounds;
  386. for ( int i = 0; i < bands.Count; i++ )
  387. {
  388. c = bands[i];
  389. bounds = c.Bounds;
  390. // adjust to gripper area
  391. bounds.X = bounds.Left - 7;
  392. bounds.Width = 7;
  393. if ( bounds.Contains(mousePoint) )
  394. {
  395. if ( bounds.Left <= 5 )
  396. {   // The left value would be actually at least 2 if the toolbar
  397. // is on the edge of the main window as opossed to be somewhere in the middle of the
  398. // strip. The assumption here is that the gripper starts approximately 2 pixel from the edge
  399. return true;
  400. }
  401. }
  402. }
  403. return false;
  404. }
  405. void NotifyChevronPushed(ref Message m)
  406. {
  407. NMREBARCHEVRON nrch = (NMREBARCHEVRON) m.GetLParam(typeof(NMREBARCHEVRON));
  408. REBARBANDINFO rb;
  409. int bandIndex = nrch.uBand;
  410. rb = GetRebarInfo(bandIndex);
  411. int actualIndex = rb.wID;
  412. Control band = (Control)bands[actualIndex];
  413. Point point = new Point(nrch.rc.left, nrch.rc.bottom);
  414. (band as IChevron).Show(this, point);
  415. }
  416. void NotifyChildSize()
  417. {
  418. for ( int i = 0; i < bands.Count; i++ )
  419. {
  420. // Update toolbar specific information
  421. // This update is to guarantee that the toolbar can resize
  422. // the buttons appropiately in case the SystemMenuFont was
  423. // changed along with the system colors
  424. ToolBarEx toolBar = (ToolBarEx)bands[i];
  425. toolBar.ToolbarSizeChanged();
  426. }
  427. }
  428. void BeginUpdate()
  429. {
  430. WindowsAPI.SendMessage(Handle, Msg.WM_SETREDRAW, 0, 0);
  431. }
  432. void EndUpdate()
  433. {
  434. WindowsAPI.SendMessage(Handle, Msg.WM_SETREDRAW, 1, 0);
  435. }
  436. bool IMessageFilter.PreFilterMessage(ref Message message)
  437. {
  438. ArrayList handles = new ArrayList();
  439. IntPtr handle = Handle;
  440. while (handle != IntPtr.Zero)
  441. {
  442. handles.Add(handle);
  443. handle = WindowsAPI.GetParent(handle);
  444. }
  445. handle = message.HWnd;
  446. while (handle != IntPtr.Zero)
  447. {
  448. Msg currentMessage = (Msg)message.Msg;
  449. if (handles.Contains(handle)) 
  450. return PreProcessMessage(ref message);
  451. handle = WindowsAPI.GetParent(handle);
  452. }
  453. return false;
  454. }
  455. void RealizeBands()
  456. {
  457. ReleaseBands();
  458. BeginUpdate();
  459. for (int i = 0; i < bands.Count; i++)
  460. {
  461. REBARBANDINFO bandInfo = GetBandInfo(i, null);
  462. WindowsAPI.SendMessage(Handle, RebarMessages.RB_INSERTBANDW, i, ref bandInfo);
  463. }
  464. UpdateSize();
  465. EndUpdate();
  466. CaptureBands();
  467. if ( bands.Count == 0 && addPlaceHolderToolBar )
  468. {
  469. if ( designerInTransaction == false )
  470. {
  471. // If the designer is engage in a transaction
  472. // don't add the place holder toolbar here, defer the
  473. // addition to the PaintBackground routine so that
  474. // we avoid some painting problems
  475. addPlaceHolderToolBar = false;
  476. AddPlaceHolder();
  477. }
  478. }
  479. }
  480. internal void UpdateBand(int index)
  481. {
  482. if (!IsHandleCreated) return;
  483. BeginUpdate();
  484. // Make sure we get the right index according to the band position in the rebar
  485. // and not to the index in the toolbar collections which can or cannot match the order
  486. // in the rebar control
  487. int actualIndex = GetBandActualIndex(index);
  488. REBARBANDINFO rbbi = GetBandInfo(actualIndex, null);
  489. ToolBarEx tb = (ToolBarEx)bands[actualIndex];
  490. int idealSize = tb.GetIdealSize();
  491. rbbi.cxIdeal = idealSize;
  492. WindowsAPI.SendMessage(Handle, RebarMessages.RB_SETBANDINFOW, index, ref rbbi);
  493. UpdateSize();
  494. EndUpdate();
  495. }
  496. int GetBandActualIndex(int bandIndex)
  497. {
  498. // This maps between the indexes in the band collection and the actual
  499. // indexes in the rebar that can actually change as the user moves
  500. // the bands around
  501. REBARBANDINFO rb;
  502. rb = GetRebarInfo(bandIndex);
  503. return rb.wID;
  504. }
  505. void UpdateSize()
  506. {
  507. Height = WindowsAPI.SendMessage(Handle, (int)RebarMessages.RB_GETBARHEIGHT, 0, 0) + 1;
  508. if ( Height == 1 )
  509. {
  510. // Give it some size
  511. RECT rc = new RECT();
  512. rc.bottom = 24;
  513. WindowsAPI.SendMessage(Handle, (int)RebarMessages.RB_SIZETORECT, 0, ref rc);
  514. }
  515. }
  516. public int GetRebarHeight()
  517. {
  518. int height = WindowsAPI.SendMessage(Handle, (int)RebarMessages.RB_GETBARHEIGHT, 0, 0) + 1;
  519. return height;
  520. }
  521. public Rectangle GetBandRect(int bandIndex)
  522. {
  523. RECT rect = new RECT();
  524. int index = GetBandActualIndex(bandIndex);
  525. WindowsAPI.SendMessage(Handle, (int)RebarMessages.RB_GETRECT, bandIndex, ref rect);
  526. return new Rectangle(rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top);
  527. }
  528. REBARBANDINFO GetRebarInfo(int index)
  529. {
  530. REBARBANDINFO rbbi = new REBARBANDINFO();
  531. rbbi.cbSize = Marshal.SizeOf(typeof(REBARBANDINFO));
  532. rbbi.fMask = RebarInfoMask.RBBIM_ID|RebarInfoMask.RBBIM_IDEALSIZE;
  533. WindowsAPI.SendMessage(Handle, RebarMessages.RB_GETBANDINFOW, index, ref rbbi);
  534. return rbbi;
  535. }
  536. REBARBANDINFO GetBandInfo(int index, Control currentBand)
  537. {
  538. bool placeHolder = false;
  539. Control band;
  540. if ( currentBand != null )
  541. {
  542. placeHolder = true;
  543. band = currentBand;
  544. }
  545. else
  546. band = bands[index];
  547. REBARBANDINFO rbbi = new REBARBANDINFO();
  548. rbbi.cbSize = Marshal.SizeOf(typeof(REBARBANDINFO));
  549. if ( !IsCommonCtrl6() )
  550. {
  551. rbbi.fMask = RebarInfoMask.RBBIM_COLORS;
  552. Color toolBarBackColor = band.BackColor;
  553.                 rbbi.clrBack = (int)ColorUtil.RGB(toolBarBackColor.R,
  554. toolBarBackColor.G, toolBarBackColor.B);
  555. rbbi.clrFore = (int)ColorUtil.RGB(255,0,255);
  556. }
  557. rbbi.iImage = 0;
  558. if ( band.BackgroundImage != null )
  559. {
  560. Bitmap bitmap = band.BackgroundImage as Bitmap;
  561. if ( bitmap != null )
  562. {
  563. rbbi.hbmBack = bitmap.GetHbitmap();
  564. rbbi.fMask = RebarInfoMask.RBBIM_BACKGROUND;
  565. }
  566. }
  567. else
  568. rbbi.hbmBack = IntPtr.Zero;
  569. rbbi.lParam = 0;
  570. rbbi.cxHeader = 0;
  571. rbbi.fMask |= RebarInfoMask.RBBIM_ID;
  572. rbbi.wID = index;
  573. if ((band.Text != null) && (band.Text != string.Empty))
  574. {
  575. rbbi.fMask |= RebarInfoMask.RBBIM_TEXT;
  576. rbbi.lpText = Marshal.StringToHGlobalAnsi(band.Text);
  577. rbbi.cch = (band.Text == null) ? 0 : band.Text.Length;
  578. }
  579. rbbi.fMask |= RebarInfoMask.RBBIM_STYLE;
  580. rbbi.fStyle = RebarStylesEx.RBBS_CHILDEDGE | RebarStylesEx.RBBS_FIXEDBMP;
  581. if ( placeHolder == false )
  582. rbbi.fStyle |= RebarStylesEx.RBBS_GRIPPERALWAYS;
  583. ToolBarEx tb = (ToolBarEx)band;
  584. if ( tb.UseNewRow == true)
  585. rbbi.fStyle |= RebarStylesEx.RBBS_BREAK;
  586. rbbi.fStyle |= (band is IChevron) ? RebarStylesEx.RBBS_USECHEVRON : 0;
  587. rbbi.fMask |= RebarInfoMask.RBBIM_CHILD;
  588. rbbi.hwndChild = band.Handle;
  589. rbbi.fMask |= RebarInfoMask.RBBIM_CHILDSIZE;
  590. rbbi.cyMinChild = band.Height;
  591. rbbi.cxMinChild = 0;
  592. rbbi.cyChild = 0;
  593. rbbi.cyMaxChild = 0; 
  594. rbbi.cyIntegral = 0;
  595. rbbi.fMask |= RebarInfoMask.RBBIM_SIZE;
  596. rbbi.cx = band.Width;
  597. rbbi.fMask |= RebarInfoMask.RBBIM_IDEALSIZE;
  598. rbbi.cxIdeal = band.Width;
  599. return rbbi;
  600. }
  601. internal void UpdateBands()
  602. {
  603. if (IsHandleCreated) 
  604. {
  605. RecreateHandle();
  606. }
  607. }
  608. void Bands_Changed(Object s, EventArgs e)
  609. {
  610. UpdateBands();
  611. }
  612. void Band_HandleCreated(Object s, EventArgs e)
  613. {
  614. ReleaseBands();
  615. ToolBarEx band = (ToolBarEx) s;
  616. UpdateBand(bands.IndexOf(band));
  617. CaptureBands();
  618. }
  619. void Band_TextChanged(Object s, EventArgs e)
  620. {
  621. ToolBarEx band = (ToolBarEx) s;
  622. UpdateBand(bands.IndexOf(band));
  623. }
  624. void CaptureBands()
  625. {
  626. foreach (Control band in bands)
  627. {
  628. band.HandleCreated += new EventHandler(Band_HandleCreated);
  629. band.TextChanged += new EventHandler(Band_TextChanged);
  630. }
  631. }
  632. void ReleaseBands()
  633. {
  634. foreach (Control band in bands)
  635. {
  636. band.HandleCreated -= new EventHandler(Band_HandleCreated);
  637. band.TextChanged -= new EventHandler(Band_TextChanged);
  638. }
  639. }
  640. }
  641. #endregion
  642. }