TabControl.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  1. // Permission is hereby granted, free of charge, to any person obtaining
  2. // a copy of this software and associated documentation files (the
  3. // "Software"), to deal in the Software without restriction, including
  4. // without limitation the rights to use, copy, modify, merge, publish,
  5. // distribute, sublicense, and/or sell copies of the Software, and to
  6. // permit persons to whom the Software is furnished to do so, subject to
  7. // the following conditions:
  8. //
  9. // The above copyright notice and this permission notice shall be
  10. // included in all copies or substantial portions of the Software.
  11. //
  12. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  13. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  14. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  15. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  16. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  17. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  18. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  19. //
  20. // Copyright (c) 2004 Novell, Inc.
  21. //
  22. // Authors:
  23. // Jackson Harper ([email protected])
  24. using System;
  25. using System.Drawing;
  26. using System.Collections;
  27. namespace System.Windows.Forms {
  28. public class TabControl : Control {
  29. private int selected_index = -1;
  30. private TabAlignment alignment;
  31. private TabAppearance appearance;
  32. private TabDrawMode draw_mode;
  33. private bool multiline;
  34. private ImageList image_list;
  35. private Size item_size;
  36. private Point padding;
  37. private int row_count = 1;
  38. private bool hottrack;
  39. private TabPageCollection tab_pages;
  40. private bool show_tool_tips;
  41. private TabSizeMode size_mode;
  42. private bool redraw;
  43. public TabControl ()
  44. {
  45. tab_pages = new TabPageCollection (this);
  46. }
  47. public TabAlignment Alignment {
  48. get { return alignment; }
  49. set {
  50. if (alignment == value)
  51. return;
  52. alignment = value;
  53. if (alignment == TabAlignment.Left || alignment == TabAlignment.Right)
  54. multiline = true;
  55. Refresh ();
  56. }
  57. }
  58. public TabAppearance Appearance {
  59. get { return appearance; }
  60. set {
  61. if (appearance == value)
  62. return;
  63. appearance = value;
  64. Refresh ();
  65. }
  66. }
  67. public override Color BackColor {
  68. get { return base.BackColor; }
  69. set { /* nothing happens on set on MS */ }
  70. }
  71. public override Image BackgroundImage {
  72. get { return base.BackgroundImage; }
  73. set { base.BackgroundImage = value; }
  74. }
  75. public override Rectangle DisplayRectangle {
  76. get { return base.DisplayRectangle; }
  77. }
  78. public TabDrawMode DrawMode {
  79. get { return draw_mode; }
  80. set {
  81. if (draw_mode == value)
  82. return;
  83. draw_mode = value;
  84. Refresh ();
  85. }
  86. }
  87. public override Color ForeColor {
  88. get { return base.ForeColor; }
  89. set { base.ForeColor = value; }
  90. }
  91. public bool HotTrack {
  92. get { return hottrack; }
  93. set {
  94. if (hottrack == value)
  95. return;
  96. hottrack = value;
  97. Refresh ();
  98. }
  99. }
  100. public ImageList ImageList {
  101. get { return image_list; }
  102. set { image_list = value; }
  103. }
  104. public Size ItemSize {
  105. get {
  106. if (item_size != Size.Empty)
  107. return item_size;
  108. if (!IsHandleCreated)
  109. return DefaultItemSize;
  110. return TabSize;
  111. }
  112. set {
  113. if (value.Height < 0 || value.Width < 0)
  114. throw new ArgumentException ("'" + value + "' is not a valid value for 'ItemSize'.");
  115. item_size = value;
  116. Refresh ();
  117. }
  118. }
  119. public bool Multiline {
  120. get { return multiline; }
  121. set {
  122. if (multiline == value)
  123. return;
  124. multiline = value;
  125. if (!multiline && alignment == TabAlignment.Left || alignment == TabAlignment.Right)
  126. alignment = TabAlignment.Top;
  127. Refresh ();
  128. }
  129. }
  130. public Point Padding {
  131. get { return padding; }
  132. set {
  133. if (value.X < 0 || value.Y < 0)
  134. throw new ArgumentException ("'" + value + "' is not a valid value for 'Padding'.");
  135. if (padding == value)
  136. return;
  137. padding = value;
  138. Refresh ();
  139. }
  140. }
  141. public int RowCount {
  142. get { return row_count; }
  143. }
  144. public int SelectedIndex {
  145. get { return selected_index; }
  146. set {
  147. if (selected_index == value)
  148. return;
  149. if (selected_index < -1) {
  150. throw new ArgumentException ("'" + value + "' is not a valid value for 'value'. " +
  151. "'value' must be greater than or equal to -1.");
  152. }
  153. // OnSelectedIndexChanged (EventArgs.Empty);
  154. Refresh ();
  155. }
  156. }
  157. public TabPage SelectedTab {
  158. get {
  159. if (selected_index == -1)
  160. return null;
  161. return tab_pages [selected_index];
  162. }
  163. set {
  164. int index = IndexForTabPage (value);
  165. if (index == selected_index)
  166. return;
  167. selected_index = index;
  168. Refresh ();
  169. }
  170. }
  171. public bool ShowToolTips {
  172. get { return show_tool_tips; }
  173. set {
  174. if (show_tool_tips == value)
  175. return;
  176. show_tool_tips = value;
  177. Refresh ();
  178. }
  179. }
  180. public TabSizeMode SizeMode {
  181. get { return size_mode; }
  182. set {
  183. if (size_mode == value)
  184. return;
  185. size_mode = value;
  186. Refresh ();
  187. }
  188. }
  189. public int TabCount {
  190. get {
  191. return tab_pages.Count;
  192. }
  193. }
  194. public TabPageCollection TabPages {
  195. get { return tab_pages; }
  196. }
  197. public override string Text {
  198. get { return base.Text; }
  199. set { base.Text = value; }
  200. }
  201. [MonoTODO ("Anything special need to be done?")]
  202. protected override CreateParams CreateParams {
  203. get {
  204. CreateParams c = base.CreateParams;
  205. // Do we need to do anything here?
  206. return c;
  207. }
  208. }
  209. protected override Size DefaultSize {
  210. get { return new Size (200, 100); }
  211. }
  212. [MonoTODO]
  213. private Size TabSize {
  214. get {
  215. return new Size ();
  216. }
  217. }
  218. [MonoTODO]
  219. private Size DefaultItemSize {
  220. get {
  221. return new Size ();
  222. }
  223. }
  224. public new event EventHandler BackColorChanged {
  225. add { base.BackColorChanged += value; }
  226. remove { base.BackColorChanged -= value; }
  227. }
  228. public new event EventHandler BackgroundImageChanged {
  229. add { base.BackgroundImageChanged += value; }
  230. remove { base.BackgroundImageChanged -= value; }
  231. }
  232. public new event EventHandler ForeColorChanged {
  233. add { base.ForeColorChanged += value; }
  234. remove { base.ForeColorChanged -= value; }
  235. }
  236. public new event PaintEventHandler Paint {
  237. add { base.Paint += value; }
  238. remove { base.Paint -= value; }
  239. }
  240. public new event EventHandler TextChanged {
  241. add { base.TextChanged += value; }
  242. remove { base.TextChanged -= value; }
  243. }
  244. public event EventHandler DrawItem;
  245. public event EventHandler SelectedIndexChanged;
  246. public Control GetControl (int index)
  247. {
  248. return GetTab (index);
  249. }
  250. protected override Control.ControlCollection CreateControlsInstance ()
  251. {
  252. return new TabControl.ControlCollection (this);
  253. }
  254. protected override void CreateHandle ()
  255. {
  256. base.CreateHandle ();
  257. }
  258. protected override void Dispose (bool disposing)
  259. {
  260. base.Dispose (disposing);
  261. }
  262. protected virtual object [] GetItems ()
  263. {
  264. TabPage [] pages = new TabPage [Controls.Count];
  265. Controls.CopyTo (pages, 0);
  266. return pages;
  267. }
  268. protected virtual object [] GetItems (Type type)
  269. {
  270. object [] pages = (object []) Array.CreateInstance (type, Controls.Count);
  271. Controls.CopyTo (pages, 0);
  272. return pages;
  273. }
  274. protected string GetToolTipText (object item)
  275. {
  276. TabPage page = (TabPage) item;
  277. return page.ToolTipText;
  278. }
  279. protected override void WndProc (ref Message m)
  280. {
  281. switch ((Msg) m.Msg) {
  282. case Msg.WM_PAINT:
  283. PaintEventArgs paint_event;
  284. paint_event = XplatUI.PaintEventStart (Handle);
  285. PaintInternal (paint_event);
  286. XplatUI.PaintEventEnd (Handle);
  287. break;
  288. default:
  289. base.WndProc (ref m);
  290. break;
  291. }
  292. }
  293. internal void UpdateTabpage (TabPage page)
  294. {
  295. }
  296. internal int IndexForTabPage (TabPage page)
  297. {
  298. for (int i = 0; i < tab_pages.Count; i++) {
  299. if (page == tab_pages [i])
  300. return i;
  301. }
  302. return -1;
  303. }
  304. private void PaintInternal (PaintEventArgs pe)
  305. {
  306. if (this.Width <= 0 || this.Height <= 0 || this.Visible == false)
  307. return;
  308. Draw ();
  309. pe.Graphics.DrawImage (this.ImageBuffer, pe.ClipRectangle, pe.ClipRectangle, GraphicsUnit.Pixel);
  310. // On MS the Paint event never seems to be raised
  311. }
  312. private void Redraw (bool recalculate)
  313. {
  314. if (recalculate) {
  315. }
  316. redraw = true;
  317. Refresh ();
  318. }
  319. private void Draw ()
  320. {
  321. if (redraw) {
  322. }
  323. redraw = false;
  324. }
  325. private TabPage GetTab (int index)
  326. {
  327. return Controls [index] as TabPage;
  328. }
  329. private void SetTab (int index, TabPage value)
  330. {
  331. ((IList) Controls).Insert (index, value);
  332. Refresh ();
  333. }
  334. public class ControlCollection : System.Windows.Forms.Control.ControlCollection {
  335. public ControlCollection (TabControl owner) : base (owner)
  336. {
  337. }
  338. public override void Add (Control value)
  339. {
  340. if (!(value is TabPage))
  341. throw new ArgumentException ("Cannot add " +
  342. value.GetType ().Name + " to TabControl. " +
  343. "Only TabPages can be directly added to TabControls.");
  344. base.Add (value);
  345. }
  346. }
  347. public class TabPageCollection : IList, ICollection, IEnumerable {
  348. private TabControl owner;
  349. private IList controls;
  350. public TabPageCollection (TabControl owner)
  351. {
  352. if (owner == null)
  353. throw new ArgumentNullException ("Value cannot be null.");
  354. this.owner = owner;
  355. controls = owner.Controls;
  356. }
  357. public virtual int Count {
  358. get { return owner.Controls.Count; }
  359. }
  360. public virtual bool IsReadOnly {
  361. get { return false; }
  362. }
  363. public virtual TabPage this [int index] {
  364. get {
  365. return owner.GetTab (index);
  366. }
  367. set {
  368. owner.SetTab (index, value);
  369. }
  370. }
  371. bool ICollection.IsSynchronized {
  372. get { return false; }
  373. }
  374. object ICollection.SyncRoot {
  375. get { return this; }
  376. }
  377. bool IList.IsFixedSize {
  378. get { return false; }
  379. }
  380. object IList.this [int index] {
  381. get {
  382. return owner.GetTab (index);
  383. }
  384. set {
  385. owner.SetTab (index, (TabPage) value);
  386. }
  387. }
  388. public void Add (TabPage page)
  389. {
  390. if (page == null)
  391. throw new ArgumentNullException ("Value cannot be null.");
  392. owner.Controls.Add (page);
  393. }
  394. public void AddRange (TabPage [] pages)
  395. {
  396. if (pages == null)
  397. throw new ArgumentNullException ("Value cannot be null.");
  398. owner.Controls.AddRange (pages);
  399. }
  400. public virtual void Clear ()
  401. {
  402. owner.Controls.Clear ();
  403. }
  404. public bool Contains (TabPage page)
  405. {
  406. if (page == null)
  407. throw new ArgumentNullException ("Value cannot be null.");
  408. return owner.Controls.Contains (page);
  409. }
  410. public virtual IEnumerator GetEnumerator ()
  411. {
  412. return owner.Controls.GetEnumerator ();
  413. }
  414. public int IndexOf (TabPage page)
  415. {
  416. return owner.Controls.IndexOf (page);
  417. }
  418. public void Remove (TabPage page)
  419. {
  420. owner.Controls.Remove (page);
  421. }
  422. public virtual void RemoveAt (int index)
  423. {
  424. owner.Controls.RemoveAt (index);
  425. }
  426. void ICollection.CopyTo (Array dest, int index)
  427. {
  428. owner.Controls.CopyTo (dest, index);
  429. }
  430. int IList.Add (object value)
  431. {
  432. // return owner.Controls.Add ((TabPage) value);
  433. return -1;
  434. }
  435. bool IList.Contains (object page)
  436. {
  437. return Contains ((TabPage) page);
  438. }
  439. int IList.IndexOf (object page)
  440. {
  441. return IndexOf ((TabPage) page);
  442. }
  443. void IList.Insert (int index, object value)
  444. {
  445. controls.Insert (index, (TabPage) value);
  446. }
  447. void IList.Remove (object value)
  448. {
  449. Remove ((TabPage) value);
  450. }
  451. }
  452. }
  453. }