CollectionEditorTest.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729
  1. using System;
  2. using System.Windows.Forms;
  3. using System.ComponentModel;
  4. using System.Collections;
  5. using System.Collections.Specialized;
  6. using System.Drawing.Design;
  7. using System.Drawing;
  8. using System.Globalization;
  9. using System.ComponentModel.Design.Serialization;
  10. using Test.Items;
  11. using Test.CollectionEditors;
  12. using Test.Collections;
  13. using Test.TypeConverters;
  14. namespace Test
  15. {
  16. #region "Test Control"
  17. public class TestControl:CustomControls.Win32Controls.PushButton,ISupportUniqueName
  18. {
  19. #region "Variables"
  20. private SimpleItem _SimpleItem= new SimpleItem();
  21. private SimpleItem_BasicTc _SimpleItem_BasicTc= new SimpleItem_BasicTc();
  22. private SimpleItem_FullTc _SimpleItem_FullTc= new SimpleItem_FullTc();
  23. private SimpleItem_Component _SimpleItem_Component= new SimpleItem_Component();
  24. private ComplexItem _ComplexItem= new ComplexItem();
  25. private SimpleItems _SimpleItems= new SimpleItems();
  26. private ComplexItems _ComplexItems=new ComplexItems();
  27. private SimpleItems _CustomItems= new SimpleItems();
  28. #endregion
  29. #region "Properties"
  30. [Category("Member Persisting")]
  31. [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
  32. public SimpleItem SimpleItem
  33. {
  34. get{return _SimpleItem;}
  35. }
  36. [Category("Member Persisting")]
  37. public SimpleItem_BasicTc SimpleItem_BasicTc
  38. {
  39. get{return _SimpleItem_BasicTc;}
  40. set{_SimpleItem_BasicTc= value;}
  41. }
  42. [Category("Member Persisting")]
  43. public SimpleItem_FullTc SimpleItem_FullTc
  44. {
  45. get{return _SimpleItem_FullTc;}
  46. set{_SimpleItem_FullTc=value;}
  47. }
  48. [Category("Member Persisting")]
  49. [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
  50. public SimpleItem_Component SimpleItem_Component
  51. {
  52. get{return _SimpleItem_Component;}
  53. }
  54. [Category("Member Persisting")]
  55. public ComplexItem ComplexItem
  56. {
  57. get{return _ComplexItem;}
  58. set{_ComplexItem=value;}
  59. }
  60. [Category ("Collections")]
  61. [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
  62. [Editor(typeof(SimpleItem_CollectionEditor),typeof(System.Drawing.Design.UITypeEditor))]
  63. public SimpleItems SimpleItems
  64. {
  65. get{return _SimpleItems;}
  66. }
  67. [Category ("Collections")]
  68. [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
  69. [Editor(typeof(ComplexItemCollectionEditor),typeof(System.Drawing.Design.UITypeEditor))]
  70. public ComplexItems ComplexItems
  71. {
  72. get{return _ComplexItems;}
  73. }
  74. [Category ("Collections")]
  75. [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
  76. [Editor(typeof(CustomItemCollectionEditor),typeof(System.Drawing.Design.UITypeEditor))]
  77. public SimpleItems CustomItems
  78. {
  79. get{return _CustomItems;}
  80. }
  81. #endregion
  82. #region "Constructors"
  83. public TestControl()
  84. {
  85. SetStyle(ControlStyles.ResizeRedraw,true);
  86. }
  87. #endregion
  88. #region "Overrides"
  89. protected override Size DefaultSize
  90. {
  91. get
  92. {
  93. return new Size(100,100);
  94. }
  95. }
  96. protected override void OnPaintBackground(PaintEventArgs pevent)
  97. {
  98. // base.OnPaintBackground (pevent);
  99. // ControlPaint.DrawBorder3D(pevent.Graphics,this.DisplayRectangle,Border3DStyle.Etched);
  100. // SizeF textSize=pevent.Graphics.MeasureString(Text,Font);
  101. // int y=Math.Max(1,(int)(Height-textSize.Height))/2;
  102. // int x=Math.Max(1,(int)(Width-textSize.Width))/2;
  103. //
  104. // RectangleF rect = new RectangleF(x,y,Width,textSize.Height);
  105. // pevent.Graphics.DrawString(Text,Font, new SolidBrush(ForeColor),rect);
  106. }
  107. #endregion
  108. #region "Implementation"
  109. public string GetUniqueName()
  110. {
  111. return GetName("ComplexItem",this.ComplexItems.Count+1);
  112. }
  113. public string GetName(string name,int index)
  114. {
  115. foreach(ComplexItem ci in this.ComplexItems )
  116. {
  117. if(ci.Name==name+index.ToString()){return GetName(name, index+1);}
  118. }
  119. return name+index.ToString();
  120. }
  121. public bool ShouldSerializeSimpleItem_FullTc()
  122. {
  123. return (SimpleItem_FullTc.Id!=-1 || SimpleItem_FullTc.Name!="SimpleItem FullTC");
  124. }
  125. public void ResetSimpleItem_FullTc()
  126. {
  127. this.SimpleItem_FullTc= new SimpleItem_FullTc();
  128. }
  129. public bool ShouldSerializeSimpleItem_BasicTc()
  130. {
  131. return (SimpleItem_BasicTc.Id!=-1 || SimpleItem_BasicTc.Name!="SimpleItem BasicTC");
  132. }
  133. public void ResetSimpleItem_BasicTc()
  134. {
  135. this.SimpleItem_BasicTc= new SimpleItem_BasicTc();
  136. }
  137. public bool ShouldSerializeSimpleItem_Component()
  138. {
  139. return (SimpleItem_Component.Id!=-1 || SimpleItem_Component.Name!="SimpleItem Comp");
  140. }
  141. public void ResetSimpleItem_Component()
  142. {
  143. this.SimpleItem_Component.Id=-1;
  144. this.SimpleItem_Component.Name="SimpleItem Comp";
  145. }
  146. public bool ShouldSerializeComplexItem()
  147. {
  148. return (ComplexItem.Id!=-1 || ComplexItem.Name!="ComplexItem" || ComplexItem.ComplexItems.Count>0);
  149. }
  150. public void ResetComplexItem()
  151. {
  152. this.ComplexItem= new ComplexItem();
  153. }
  154. #endregion
  155. }
  156. #endregion
  157. namespace Items
  158. {
  159. public class SimpleItem
  160. {
  161. // A verry simple Item
  162. private string _Name="SimpleItem";
  163. private int _Id=-1;
  164. [Category("TestProperties")] // Take this out, and you will soon have problems with serialization;
  165. [DefaultValue(typeof(string),"")]
  166. [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
  167. public string Name
  168. {
  169. get{return _Name;}
  170. set{_Name= value;}
  171. }
  172. [Category("TestProperties")]
  173. [DefaultValue(typeof(int),"-1")]
  174. [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
  175. public int Id
  176. {
  177. get{return _Id;}
  178. set{_Id= value;}
  179. }
  180. public SimpleItem()
  181. {
  182. }
  183. public SimpleItem(int Id, string Name)
  184. {
  185. this._Id=Id;
  186. this._Name= Name;
  187. }
  188. }
  189. [TypeConverter(typeof(SimpleItemFullConverter))]
  190. public class SimpleItem_FullTc:SimpleItem
  191. {
  192. // A class that inherits from SimpleItem, and has an custom 'full initialization' TypeConverter
  193. public SimpleItem_FullTc():base(-1,"SimpleItem FullTC")
  194. {}
  195. public SimpleItem_FullTc(int Id, string Name):base(Id,Name)
  196. {
  197. }
  198. }
  199. [TypeConverter(typeof(SimpleItemBasicConverter))]
  200. public class SimpleItem_BasicTc:SimpleItem
  201. {
  202. //A class that inherits from SimpleItem, and has an custom 'basic' TypeConverter
  203. public SimpleItem_BasicTc():base(-1,"SimpleItem BasicTC")
  204. {}
  205. }
  206. // If you don't want to appear in the Component Tray uncoment the next line.
  207. // [DesignTimeVisible(false)]
  208. public class SimpleItem_Component:SimpleItem,IComponent
  209. {
  210. //A class that inherits from SimpleItem and implements IComponent
  211. public event EventHandler Disposed; //Implement IComponent.Disposed
  212. private ISite _curISBNSite;
  213. public virtual void Dispose() //Implement IComponent.Dispose()
  214. {
  215. //There is nothing to clean.
  216. if(Disposed != null)
  217. {
  218. Disposed(this,EventArgs.Empty);
  219. }
  220. }
  221. [Browsable(false)]
  222. public virtual ISite Site //implements IComponent.Site
  223. {
  224. get
  225. {
  226. return _curISBNSite;
  227. }
  228. set
  229. {
  230. _curISBNSite = value;
  231. }
  232. }
  233. public SimpleItem_Component():base(-1,"SimpleItem Comp")
  234. {
  235. // IComponent also requires a simple constructor...
  236. }
  237. }
  238. [TypeConverter(typeof(ComplexItemConverter))]
  239. public class ComplexItem:SimpleItem,ISupportUniqueName
  240. {
  241. private ComplexItems _ComplexItems= new ComplexItems();
  242. [Category ("Collections")]
  243. [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
  244. [Editor(typeof(ComplexItemCollectionEditor),typeof(System.Drawing.Design.UITypeEditor))]
  245. public virtual ComplexItems ComplexItems
  246. {
  247. get{return _ComplexItems;}
  248. }
  249. public ComplexItem():base(-1,"ComplexItem")
  250. {}
  251. public ComplexItem(int Id, string Name,ComplexItem[] complexItems):base(Id,Name)
  252. {
  253. this.ComplexItems.AddRange(complexItems);
  254. }
  255. public string GetUniqueName()
  256. {
  257. return GetName("SubItem",this.ComplexItems.Count+1);
  258. }
  259. public string GetName(string name,int index)
  260. {
  261. foreach(ComplexItem ci in this.ComplexItems )
  262. {
  263. if(ci.Name==name+index.ToString()){return GetName(name, index+1);}
  264. }
  265. return name+index.ToString();
  266. }
  267. }
  268. }
  269. namespace Collections
  270. {
  271. public class SimpleItems:CollectionBase
  272. {
  273. public SimpleItems()
  274. {}
  275. public SimpleItem Add(SimpleItem si)
  276. {
  277. this.InnerList.Add(si);
  278. return si;
  279. }
  280. public void Remove(SimpleItem si)
  281. {
  282. this.InnerList.Remove(si);
  283. }
  284. public bool Contains(SimpleItem si)
  285. {
  286. return this.InnerList.Contains(si);
  287. }
  288. public SimpleItem this[int i]
  289. {
  290. get{return (SimpleItem)this.InnerList[i];}
  291. set{this.InnerList[i]=value;}
  292. }
  293. public void AddRange(SimpleItem[] si)
  294. {
  295. this.InnerList.AddRange(si);
  296. }
  297. public SimpleItem[] GetValues()
  298. {
  299. SimpleItem[] si= new SimpleItem[this.InnerList.Count];
  300. this.InnerList.CopyTo(0,si,0,this.InnerList.Count);
  301. return si;
  302. }
  303. protected override void OnInsert(int index, object value)
  304. {
  305. base.OnInsert (index, value);
  306. }
  307. }
  308. public class ComplexItems:CollectionBase
  309. {
  310. public ComplexItems()
  311. {}
  312. public ComplexItem Add(ComplexItem ci)
  313. {
  314. this.InnerList.Add(ci);
  315. return ci;
  316. }
  317. public void AddRange(ComplexItem[] ci)
  318. {
  319. this.InnerList.AddRange(ci);
  320. }
  321. public void Remove(ComplexItem ci)
  322. {
  323. this.InnerList.Remove(ci);
  324. }
  325. public bool Contains(ComplexItem ci)
  326. {
  327. return this.InnerList.Contains(ci);
  328. }
  329. public ComplexItem this[int i]
  330. {
  331. get{return (ComplexItem)this.InnerList[i];}
  332. set{this.InnerList[i]=value;}
  333. }
  334. public ComplexItem[] GetValues()
  335. {
  336. //It is used by the ComplexItemConverter
  337. ComplexItem[] ci= new ComplexItem[this.InnerList.Count];
  338. this.InnerList.CopyTo(0,ci,0,this.InnerList.Count);
  339. return ci;
  340. }
  341. }
  342. }
  343. namespace TypeConverters
  344. {
  345. internal class SimpleItemFullConverter:ExpandableObjectConverter
  346. {
  347. public override bool CanConvertFrom(ITypeDescriptorContext context,Type t)
  348. {
  349. if (t==typeof(string)){return true;}
  350. return base.CanConvertFrom(context ,t);
  351. }
  352. public override bool CanConvertTo(ITypeDescriptorContext context, Type destType)
  353. {
  354. if (destType == typeof(InstanceDescriptor) || destType == typeof(string))
  355. {
  356. return true;
  357. }
  358. return base.CanConvertTo(context, destType);
  359. }
  360. public override object ConvertFrom(ITypeDescriptorContext context,CultureInfo info,object value)
  361. {
  362. if (value is string)
  363. {
  364. string str=(string)value;
  365. try
  366. {
  367. string[] elements=str.Split(new char[] {';',':'});
  368. return new SimpleItem_FullTc(int.Parse(elements[1]),elements[3]);
  369. }
  370. catch
  371. {
  372. return new SimpleItem_FullTc();
  373. }
  374. }
  375. return base.ConvertFrom(context,info,value);
  376. }
  377. public override object ConvertTo(ITypeDescriptorContext context,CultureInfo info,object value,Type destType )
  378. {
  379. if (destType==typeof(string))
  380. {
  381. SimpleItem_FullTc si=(SimpleItem_FullTc)value;
  382. return "Id : "+ si.Id.ToString() +";"+" Name : " + si.Name;
  383. }
  384. else if (destType == typeof(InstanceDescriptor))
  385. {
  386. return new InstanceDescriptor(typeof(SimpleItem_FullTc).GetConstructor(new Type[]{typeof(int), typeof(string)}), new object[]{((SimpleItem_FullTc)value).Id,((SimpleItem_FullTc)value).Name},true);
  387. }
  388. return base.ConvertTo(context,info,value,destType);
  389. }
  390. }
  391. internal class SimpleItemBasicConverter:ExpandableObjectConverter
  392. {
  393. public override bool CanConvertTo(ITypeDescriptorContext context, Type destType)
  394. {
  395. if (destType == typeof(InstanceDescriptor))
  396. {
  397. return true;
  398. }
  399. return base.CanConvertTo(context, destType);
  400. }
  401. public override object ConvertTo(ITypeDescriptorContext context,CultureInfo info,object value,Type destType )
  402. {
  403. if (destType == typeof(InstanceDescriptor))
  404. {
  405. return new InstanceDescriptor(typeof(SimpleItem_BasicTc).GetConstructor(new Type[0]), null,false);
  406. }
  407. return base.ConvertTo(context,info,value,destType);
  408. }
  409. }
  410. internal class ComplexItemConverter:ExpandableObjectConverter
  411. {
  412. public override bool CanConvertFrom(ITypeDescriptorContext context,Type t)
  413. {
  414. if (t==typeof(string)){return true;}
  415. return base.CanConvertFrom(context ,t);
  416. }
  417. public override bool CanConvertTo(ITypeDescriptorContext context, Type destType)
  418. {
  419. if (destType == typeof(InstanceDescriptor) || destType == typeof(string))
  420. {
  421. return true;
  422. }
  423. return base.CanConvertTo(context, destType);
  424. }
  425. public override object ConvertFrom(ITypeDescriptorContext context,CultureInfo info,object value)
  426. {
  427. if (value is string)
  428. {
  429. string str=(string)value;
  430. try
  431. {
  432. string[] elements=str.Split(new char[] {';',':'});
  433. return new ComplexItem(int.Parse(elements[1]),elements[3],null);
  434. }
  435. catch
  436. {
  437. return new ComplexItem();
  438. }
  439. }
  440. return base.ConvertFrom(context,info,value);
  441. }
  442. public override object ConvertTo(ITypeDescriptorContext context,CultureInfo info,object value,Type destType )
  443. {
  444. if ((destType==typeof(string)))
  445. {
  446. ComplexItem ci=(ComplexItem)value;
  447. return "Id : "+ ci.Id.ToString() +";"+" Name : " + ci.Name;
  448. }
  449. else if (destType == typeof(InstanceDescriptor))
  450. {
  451. return new InstanceDescriptor(typeof(ComplexItem).GetConstructor(new Type[]{typeof(int), typeof(string), typeof(ComplexItem[])}), new object[]{((ComplexItem)value).Id,((ComplexItem)value).Name,((ComplexItem)value).ComplexItems.GetValues()},true);
  452. }
  453. return base.ConvertTo(context,info,value,destType);
  454. }
  455. }
  456. }
  457. namespace CollectionEditors
  458. {
  459. public class SimpleItem_CollectionEditor:System.ComponentModel.Design.CollectionEditor
  460. {
  461. // A Collection Editor for all the classes that inherits from SimpleItem
  462. private Type[] types;
  463. public SimpleItem_CollectionEditor (Type type):base(type )
  464. {
  465. types = new Type[]{typeof(SimpleItem),typeof(SimpleItem_BasicTc),typeof(SimpleItem_FullTc),typeof(SimpleItem_Component),typeof(ComplexItem) };
  466. }
  467. protected override Type[] CreateNewItemTypes()
  468. {
  469. return types;
  470. }
  471. }
  472. public class ComplexItemCollectionEditor:System.ComponentModel.Design.CollectionEditor
  473. {
  474. private CollectionForm collectionForm;
  475. public ComplexItemCollectionEditor (Type type):base(type ){}
  476. public override object EditValue( ITypeDescriptorContext context, IServiceProvider provider,object value)
  477. {
  478. if(this.collectionForm != null && this.collectionForm.Visible)
  479. {
  480. ComplexItemCollectionEditor editor = new ComplexItemCollectionEditor(this.CollectionType);
  481. return editor.EditValue(context, provider, value);
  482. }
  483. else return base.EditValue(context, provider, value);
  484. }
  485. protected override CollectionForm CreateCollectionForm()
  486. {
  487. this.collectionForm = base.CreateCollectionForm();
  488. return this.collectionForm;
  489. }
  490. protected override object CreateInstance(Type ItemType)
  491. {
  492. /* you can create the new instance yourself
  493. * ComplexItem ci=new ComplexItem(2,"ComplexItem",null);
  494. * we know for sure that the itemType it will always be ComplexItem
  495. *but this time let it to do the job...
  496. */
  497. ComplexItem ci=(ComplexItem)base.CreateInstance(ItemType);
  498. if ( this.Context.Instance!=null)
  499. {
  500. if (this.Context.Instance is ISupportUniqueName)
  501. {
  502. ci.Name=((ISupportUniqueName)this.Context.Instance).GetUniqueName();
  503. }
  504. else{ci.Name="ComplexItem";}
  505. }
  506. return ci;
  507. }
  508. }
  509. }
  510. #region "Interfaces"
  511. public interface ISupportUniqueName
  512. {
  513. string GetUniqueName();
  514. }
  515. #endregion
  516. }