PropertyGrid.cs 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772
  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-2008 Novell, Inc.
  21. //
  22. // Authors:
  23. // Jonathan Chambers ([email protected])
  24. // Ivan N. Zlatev ([email protected])
  25. //
  26. // NOT COMPLETE
  27. using System;
  28. using System.Drawing;
  29. using System.Drawing.Design;
  30. using System.ComponentModel;
  31. using System.Collections;
  32. using System.ComponentModel.Design;
  33. using System.Reflection;
  34. using System.Runtime.InteropServices;
  35. using System.Windows.Forms.Design;
  36. using System.Windows.Forms.PropertyGridInternal;
  37. namespace System.Windows.Forms {
  38. [Designer("System.Windows.Forms.Design.PropertyGridDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
  39. #if NET_2_0
  40. [ClassInterface (ClassInterfaceType.AutoDispatch)]
  41. [ComVisible (true)]
  42. #endif
  43. public class PropertyGrid : System.Windows.Forms.ContainerControl, ComponentModel.Com2Interop.IComPropertyBrowser {
  44. #region Private Members
  45. private const string UNCATEGORIZED_CATEGORY_LABEL = "Misc";
  46. private AttributeCollection browsable_attributes = null;
  47. private bool can_show_commands = false;
  48. private Color commands_back_color;
  49. private Color commands_fore_color;
  50. private bool commands_visible;
  51. private bool commands_visible_if_available;
  52. private Point context_menu_default_location;
  53. private bool large_buttons;
  54. private Color line_color;
  55. private PropertySort property_sort;
  56. private PropertyTabCollection property_tabs;
  57. private GridEntry selected_grid_item;
  58. private GridEntry root_grid_item;
  59. private object[] selected_objects;
  60. private PropertyTab selected_tab;
  61. private ImageList toolbar_imagelist;
  62. private PropertyToolBarButton categorized_toolbarbutton;
  63. private PropertyToolBarButton alphabetic_toolbarbutton;
  64. #if NET_2_0
  65. private ToolStripSeparator separator_toolbarbutton;
  66. #else
  67. private ToolBarButton separator_toolbarbutton;
  68. #endif
  69. private PropertyToolBarButton propertypages_toolbarbutton;
  70. internal PropertyToolBar toolbar;
  71. internal PropertyGridView property_grid_view;
  72. internal Splitter splitter;
  73. internal Panel help_panel;
  74. internal Label help_title_label;
  75. internal Label help_description_label;
  76. private MenuItem reset_menuitem;
  77. private MenuItem description_menuitem;
  78. private Color category_fore_color;
  79. #if NET_2_0
  80. private Color commands_active_link_color;
  81. private Color commands_disabled_link_color;
  82. private Color commands_link_color;
  83. #endif
  84. #endregion // Private Members
  85. #region Contructors
  86. public PropertyGrid ()
  87. {
  88. selected_objects = new object[0];
  89. property_tabs = new PropertyTabCollection();
  90. line_color = SystemColors.ScrollBar;
  91. category_fore_color = line_color;
  92. browsable_attributes = new AttributeCollection(new Attribute[] {});
  93. commands_visible_if_available = false;
  94. property_sort = PropertySort.CategorizedAlphabetical;
  95. property_grid_view = new PropertyGridView(this);
  96. splitter = new Splitter();
  97. splitter.Dock = DockStyle.Bottom;
  98. help_panel = new Panel();
  99. help_panel.Dock = DockStyle.Bottom;
  100. //help_panel.DockPadding.All = 3;
  101. help_panel.Height = 50;
  102. help_panel.BackColor = SystemColors.Control;
  103. help_title_label = new Label();
  104. help_title_label.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
  105. help_title_label.Name = "help_title_label";
  106. help_title_label.Font = new Font(this.Font,FontStyle.Bold);
  107. help_title_label.Location = new Point(2,2);
  108. help_title_label.Height = 17;
  109. help_title_label.Width = help_panel.Width - 4;
  110. help_description_label = new Label();
  111. help_description_label.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom;
  112. help_description_label.AutoEllipsis = true;
  113. help_description_label.AutoSize = false;
  114. help_description_label.Font = this.Font;
  115. help_description_label.Location = new Point(2,help_title_label.Top+help_title_label.Height);
  116. help_description_label.Width = help_panel.Width - 4;
  117. help_description_label.Height = help_panel.Height - help_description_label.Top - 2;
  118. help_panel.Controls.Add(help_description_label);
  119. help_panel.Controls.Add(help_title_label);
  120. help_panel.Paint+=new PaintEventHandler(help_panel_Paint);
  121. toolbar = new PropertyToolBar();
  122. toolbar.Dock = DockStyle.Top;
  123. categorized_toolbarbutton = new PropertyToolBarButton ();
  124. alphabetic_toolbarbutton = new PropertyToolBarButton ();
  125. #if NET_2_0
  126. separator_toolbarbutton = new ToolStripSeparator ();
  127. #else
  128. separator_toolbarbutton = new ToolBarButton ();
  129. #endif
  130. propertypages_toolbarbutton = new PropertyToolBarButton ();
  131. ContextMenu context_menu = new ContextMenu();
  132. toolbar_imagelist = new ImageList();
  133. toolbar_imagelist.ColorDepth = ColorDepth.Depth32Bit;
  134. toolbar_imagelist.ImageSize = new System.Drawing.Size(16, 16);
  135. toolbar_imagelist.TransparentColor = System.Drawing.Color.Transparent;
  136. toolbar_imagelist.Images.Add( (Image)Locale.GetResource( "propertygrid_sort_category") );
  137. toolbar_imagelist.Images.Add( (Image)Locale.GetResource( "propertygrid_sort_alphabetical") );
  138. toolbar_imagelist.Images.Add( (Image)Locale.GetResource( "propertygrid_tab_properties") );
  139. toolbar.Appearance = ToolBarAppearance.Flat;
  140. toolbar.AutoSize = false;
  141. toolbar.ImageList = toolbar_imagelist;
  142. toolbar.Location = new System.Drawing.Point(0, 0);
  143. toolbar.ShowToolTips = true;
  144. toolbar.Size = new System.Drawing.Size(256, 27);
  145. toolbar.TabIndex = 0;
  146. #if NET_2_0
  147. toolbar.Items.AddRange (new ToolStripItem [] {categorized_toolbarbutton,
  148. alphabetic_toolbarbutton,
  149. separator_toolbarbutton,
  150. propertypages_toolbarbutton});
  151. //toolbar.ButtonSize = new System.Drawing.Size (20, 20);
  152. toolbar.ItemClicked += new ToolStripItemClickedEventHandler (toolbar_ButtonClick);
  153. #else
  154. toolbar.Buttons.AddRange(new ToolBarButton [] {categorized_toolbarbutton,
  155. alphabetic_toolbarbutton,
  156. separator_toolbarbutton,
  157. propertypages_toolbarbutton});
  158. toolbar.ButtonSize = new System.Drawing.Size(20, 20);
  159. toolbar.ButtonClick += new ToolBarButtonClickEventHandler(toolbar_ButtonClick);
  160. separator_toolbarbutton.Style = ToolBarButtonStyle.Separator;
  161. #endif
  162. categorized_toolbarbutton.ImageIndex = 0;
  163. categorized_toolbarbutton.Style = ToolBarButtonStyle.ToggleButton;
  164. categorized_toolbarbutton.ToolTipText = Locale.GetText ("Categorized");
  165. alphabetic_toolbarbutton.ImageIndex = 1;
  166. alphabetic_toolbarbutton.Style = ToolBarButtonStyle.ToggleButton;
  167. alphabetic_toolbarbutton.ToolTipText = Locale.GetText ("Alphabetic");
  168. propertypages_toolbarbutton.Enabled = false;
  169. propertypages_toolbarbutton.ImageIndex = 2;
  170. propertypages_toolbarbutton.Style = ToolBarButtonStyle.ToggleButton;
  171. propertypages_toolbarbutton.ToolTipText = "Property Pages";
  172. reset_menuitem = context_menu.MenuItems.Add("Reset");
  173. reset_menuitem.Click +=new EventHandler(OnResetPropertyClick);
  174. context_menu.MenuItems.Add("-");
  175. description_menuitem = context_menu.MenuItems.Add("Description");
  176. description_menuitem.Click += new EventHandler(OnDescriptionClick);
  177. description_menuitem.Checked = this.HelpVisible;
  178. this.ContextMenu = context_menu;
  179. toolbar.ContextMenu = context_menu;
  180. BorderHelperControl helper = new BorderHelperControl ();
  181. helper.Dock = DockStyle.Fill;
  182. helper.Controls.Add (property_grid_view);
  183. this.Controls.Add(helper);
  184. this.Controls.Add(toolbar);
  185. this.Controls.Add(splitter);
  186. this.Controls.Add(help_panel);
  187. this.Name = "PropertyGrid";
  188. this.Size = new System.Drawing.Size(256, 400);
  189. UpdateToolBarButtons();
  190. }
  191. #endregion // Constructors
  192. #region Public Instance Properties
  193. [BrowsableAttribute(false)]
  194. [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
  195. [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
  196. public AttributeCollection BrowsableAttributes {
  197. get {
  198. return browsable_attributes;
  199. }
  200. set {
  201. if (browsable_attributes == value) {
  202. return;
  203. }
  204. browsable_attributes = value;
  205. }
  206. }
  207. [Browsable(false)]
  208. [EditorBrowsable(EditorBrowsableState.Never)]
  209. public override bool AutoScroll {
  210. get {
  211. return base.AutoScroll;
  212. }
  213. set {
  214. base.AutoScroll = value;
  215. }
  216. }
  217. public override Color BackColor {
  218. get {
  219. return base.BackColor;
  220. }
  221. set {
  222. base.BackColor = value;
  223. toolbar.BackColor = value;
  224. Refresh ();
  225. }
  226. }
  227. [Browsable(false)]
  228. [EditorBrowsable(EditorBrowsableState.Never)]
  229. public override Image BackgroundImage {
  230. get {
  231. return base.BackgroundImage;
  232. }
  233. set {
  234. base.BackgroundImage = value;
  235. }
  236. }
  237. #if NET_2_0
  238. [EditorBrowsable(EditorBrowsableState.Never)]
  239. [Browsable(false)]
  240. public override ImageLayout BackgroundImageLayout {
  241. get { return base.BackgroundImageLayout; }
  242. set { base.BackgroundImageLayout = value; }
  243. }
  244. #endif
  245. [BrowsableAttribute(false)]
  246. [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
  247. public virtual bool CanShowCommands {
  248. get {
  249. return can_show_commands;
  250. }
  251. }
  252. #if NET_2_0
  253. [DefaultValue(typeof(Color), "ControlText")]
  254. public
  255. #else
  256. internal
  257. #endif
  258. Color CategoryForeColor {
  259. get {
  260. return category_fore_color;
  261. }
  262. set {
  263. if (category_fore_color != value) {
  264. category_fore_color = value;
  265. Invalidate ();
  266. }
  267. }
  268. }
  269. public Color CommandsBackColor {
  270. get {
  271. return commands_back_color;
  272. }
  273. set {
  274. if (commands_back_color == value) {
  275. return;
  276. }
  277. commands_back_color = value;
  278. }
  279. }
  280. public Color CommandsForeColor {
  281. get {
  282. return commands_fore_color;
  283. }
  284. set {
  285. if (commands_fore_color == value) {
  286. return;
  287. }
  288. commands_fore_color = value;
  289. }
  290. }
  291. #if NET_2_0
  292. public Color CommandsActiveLinkColor {
  293. get {
  294. return commands_active_link_color;
  295. }
  296. set {
  297. commands_active_link_color = value;
  298. }
  299. }
  300. public Color CommandsDisabledLinkColor {
  301. get {
  302. return commands_disabled_link_color;
  303. }
  304. set {
  305. commands_disabled_link_color = value;
  306. }
  307. }
  308. public Color CommandsLinkColor {
  309. get {
  310. return commands_link_color;
  311. }
  312. set {
  313. commands_link_color = value;
  314. }
  315. }
  316. #endif
  317. [BrowsableAttribute (false)]
  318. [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
  319. [MonoTODO ("Commands are not implemented yet.")]
  320. public virtual bool CommandsVisible {
  321. get {
  322. return commands_visible;
  323. }
  324. }
  325. #if NET_2_0
  326. [DefaultValue (true)]
  327. #else
  328. [DefaultValue (false)]
  329. #endif
  330. public virtual bool CommandsVisibleIfAvailable {
  331. get {
  332. return commands_visible_if_available;
  333. }
  334. set {
  335. if (commands_visible_if_available == value) {
  336. return;
  337. }
  338. commands_visible_if_available = value;
  339. }
  340. }
  341. [BrowsableAttribute(false)]
  342. [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
  343. [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
  344. public Point ContextMenuDefaultLocation {
  345. get {
  346. return context_menu_default_location;
  347. }
  348. }
  349. [Browsable(false)]
  350. [EditorBrowsable(EditorBrowsableState.Never)]
  351. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  352. public new Control.ControlCollection Controls {
  353. get {
  354. return base.Controls;
  355. }
  356. }
  357. [Browsable(false)]
  358. [EditorBrowsable(EditorBrowsableState.Never)]
  359. public override Color ForeColor {
  360. get {
  361. return base.ForeColor;
  362. }
  363. set {
  364. base.ForeColor = value;
  365. }
  366. }
  367. #if NET_2_0
  368. [DefaultValue ("Color [Control]")]
  369. #endif
  370. public Color HelpBackColor {
  371. get {
  372. return help_panel.BackColor;
  373. }
  374. set {
  375. if (help_panel.BackColor == value) {
  376. return;
  377. }
  378. help_panel.BackColor = value;
  379. }
  380. }
  381. #if NET_2_0
  382. [DefaultValue ("Color [ControlText]")]
  383. #endif
  384. public Color HelpForeColor {
  385. get {
  386. return help_panel.ForeColor;
  387. }
  388. set {
  389. if (help_panel.ForeColor == value) {
  390. return;
  391. }
  392. help_panel.ForeColor = value;
  393. }
  394. }
  395. [DefaultValue(true)]
  396. [Localizable(true)]
  397. public virtual bool HelpVisible {
  398. get {
  399. return help_panel.Visible;
  400. }
  401. set {
  402. if (help_panel.Visible == value) {
  403. return;
  404. }
  405. help_panel.Visible = value;
  406. }
  407. }
  408. #if NET_2_0
  409. [DefaultValue (false)]
  410. #endif
  411. public bool LargeButtons {
  412. get {
  413. return large_buttons;
  414. }
  415. set {
  416. if (large_buttons == value) {
  417. return;
  418. }
  419. large_buttons = value;
  420. }
  421. }
  422. #if NET_2_0
  423. [DefaultValue ("Color [InactiveBorder]")]
  424. #endif
  425. public Color LineColor {
  426. get {
  427. return line_color;
  428. }
  429. set {
  430. if (line_color == value) {
  431. return;
  432. }
  433. line_color = value;
  434. }
  435. }
  436. #if NET_2_0
  437. [EditorBrowsable(EditorBrowsableState.Never)]
  438. [Browsable(false)]
  439. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  440. public new Padding Padding {
  441. get { return base.Padding; }
  442. set { base.Padding = value; }
  443. }
  444. #endif
  445. [DefaultValue(PropertySort.CategorizedAlphabetical)]
  446. public PropertySort PropertySort {
  447. get {
  448. return property_sort;
  449. }
  450. set {
  451. #if NET_2_0
  452. if (!Enum.IsDefined (typeof (PropertySort), value))
  453. throw new InvalidEnumArgumentException ("value", (int) value, typeof (PropertySort));
  454. #endif
  455. if (property_sort == value) {
  456. UpdateToolBarButtons ();
  457. return;
  458. }
  459. // we do not need to update the the grid items and fire
  460. // a PropertySortChanged event when switching between
  461. // Categorized and CateogizedAlphabetical
  462. bool needUpdate = (property_sort & PropertySort.Categorized) == 0 ||
  463. (value & PropertySort.Categorized) == 0;
  464. property_sort = value;
  465. UpdateToolBarButtons ();
  466. if (needUpdate) {
  467. UpdateSortLayout (root_grid_item);
  468. // update selection
  469. if (selected_grid_item != null) {
  470. if (selected_grid_item.GridItemType == GridItemType.Category &&
  471. (value == PropertySort.Alphabetical || value == PropertySort.NoSort))
  472. SelectItemCore (null, null);
  473. else
  474. SelectItemCore (null, selected_grid_item);
  475. }
  476. property_grid_view.UpdateView ();
  477. #if NET_2_0
  478. EventHandler eh = (EventHandler)(Events [PropertySortChangedEvent]);
  479. if (eh != null)
  480. eh (this, EventArgs.Empty);
  481. #endif
  482. }
  483. }
  484. }
  485. [BrowsableAttribute(false)]
  486. [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
  487. [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
  488. public PropertyTabCollection PropertyTabs {
  489. get {
  490. return property_tabs;
  491. }
  492. }
  493. [BrowsableAttribute(false)]
  494. [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
  495. [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
  496. public GridItem SelectedGridItem {
  497. get { return selected_grid_item; }
  498. set {
  499. if (value == null)
  500. throw new ArgumentException ("GridItem specified to PropertyGrid.SelectedGridItem must be a valid GridItem.");
  501. if (value != selected_grid_item) {
  502. GridEntry oldItem = selected_grid_item;
  503. SelectItemCore (oldItem, (GridEntry)value);
  504. OnSelectedGridItemChanged (new SelectedGridItemChangedEventArgs (oldItem, value));
  505. }
  506. }
  507. }
  508. internal GridItem RootGridItem {
  509. get { return root_grid_item; }
  510. }
  511. private void UpdateHelp (GridItem item)
  512. {
  513. if (item == null) {
  514. help_title_label.Text = string.Empty;
  515. help_description_label.Text = string.Empty;
  516. } else {
  517. help_title_label.Text = item.Label;
  518. if (item.PropertyDescriptor != null)
  519. this.help_description_label.Text = item.PropertyDescriptor.Description;
  520. }
  521. }
  522. private void SelectItemCore (GridEntry oldItem, GridEntry item)
  523. {
  524. UpdateHelp (item);
  525. selected_grid_item = item;
  526. property_grid_view.SelectItem (oldItem, item);
  527. }
  528. internal void OnPropertyValueChangedInternal (GridItem item, object property_value) {
  529. PopulateSubGridItems (selected_grid_item);
  530. property_grid_view.UpdateView ();
  531. OnPropertyValueChanged (new PropertyValueChangedEventArgs (item, property_value));
  532. }
  533. internal void OnExpandItem (GridEntry item)
  534. {
  535. property_grid_view.ExpandItem (item);
  536. }
  537. internal void OnCollapseItem (GridEntry item)
  538. {
  539. property_grid_view.CollapseItem (item);
  540. }
  541. internal DialogResult ShowError (string text)
  542. {
  543. return this.ShowError (text, MessageBoxButtons.OK);
  544. }
  545. internal DialogResult ShowError (string text, MessageBoxButtons buttons)
  546. {
  547. if (text == null)
  548. throw new ArgumentNullException ("text");
  549. return MessageBox.Show (this, text, "Properties Window", buttons, MessageBoxIcon.Exclamation);
  550. }
  551. [DefaultValue(null)]
  552. [TypeConverter("System.Windows.Forms.PropertyGrid+SelectedObjectConverter, " + Consts.AssemblySystem_Windows_Forms)]
  553. public object SelectedObject {
  554. get {
  555. if (selected_objects.Length > 0)
  556. return selected_objects[0];
  557. return null;
  558. }
  559. set {
  560. if (value == null)
  561. SelectedObjects = new object[0];
  562. else
  563. SelectedObjects = new object[] {value};
  564. }
  565. }
  566. [BrowsableAttribute(false)]
  567. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  568. public object[] SelectedObjects {
  569. get {
  570. return selected_objects;
  571. }
  572. set {
  573. if (value != null) {
  574. for (int i = 0; i < value.Length; i++) {
  575. if (value [i] == null)
  576. throw new ArgumentException (String.Format ("Item {0} in the objs array is null.", i));
  577. }
  578. selected_objects = value;
  579. } else {
  580. selected_objects = new object [0];
  581. }
  582. if (selected_objects.Length > 0) {
  583. PropertyTabAttribute[] propTabs = (PropertyTabAttribute[])this.SelectedObject.GetType().GetCustomAttributes(typeof(PropertyTabAttribute),true);
  584. if (propTabs.Length > 0) {
  585. foreach (Type tabType in propTabs[0].TabClasses) {
  586. this.PropertyTabs.AddTabType(tabType);
  587. }
  588. }
  589. } else {
  590. SelectItemCore (null, null);
  591. }
  592. RefreshTabs(PropertyTabScope.Component);
  593. PopulateGrid (selected_objects);
  594. if (root_grid_item != null)
  595. SelectItemCore (null, GetDefaultPropertyItem (root_grid_item));
  596. property_grid_view.UpdateView ();
  597. OnSelectedObjectsChanged (EventArgs.Empty);
  598. }
  599. }
  600. [BrowsableAttribute(false)]
  601. [EditorBrowsable(EditorBrowsableState.Advanced)]
  602. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  603. public PropertyTab SelectedTab {
  604. get {
  605. return selected_tab;
  606. }
  607. }
  608. public override ISite Site {
  609. get {
  610. return base.Site;
  611. }
  612. set {
  613. base.Site = value;
  614. }
  615. }
  616. #if NET_2_0
  617. [Browsable (false)]
  618. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  619. public override string Text {
  620. get {
  621. return base.Text;
  622. }
  623. set {
  624. base.Text = value;
  625. }
  626. }
  627. #endif
  628. [DefaultValue(true)]
  629. public virtual bool ToolbarVisible {
  630. get {
  631. return toolbar.Visible;
  632. }
  633. set {
  634. if (toolbar.Visible == value) {
  635. return;
  636. }
  637. toolbar.Visible = value;
  638. }
  639. }
  640. #if NET_2_0
  641. protected ToolStripRenderer ToolStripRenderer {
  642. get {
  643. if (toolbar != null) {
  644. return toolbar.Renderer;
  645. }
  646. return null;
  647. }
  648. set {
  649. if (toolbar != null) {
  650. toolbar.Renderer = value;
  651. }
  652. }
  653. }
  654. #endif
  655. #if NET_2_0
  656. [DefaultValue ("Color [Window]")]
  657. #endif
  658. public Color ViewBackColor {
  659. get {
  660. return property_grid_view.BackColor;
  661. }
  662. set {
  663. if (property_grid_view.BackColor == value) {
  664. return;
  665. }
  666. property_grid_view.BackColor = value;
  667. }
  668. }
  669. #if NET_2_0
  670. [DefaultValue ("Color [WindowText]")]
  671. #endif
  672. public Color ViewForeColor {
  673. get {
  674. return property_grid_view.ForeColor;
  675. }
  676. set {
  677. if (property_grid_view.ForeColor == value) {
  678. return;
  679. }
  680. property_grid_view.ForeColor = value;
  681. }
  682. }
  683. #if NET_2_0
  684. [DefaultValue (false)]
  685. public bool UseCompatibleTextRendering {
  686. get {
  687. return use_compatible_text_rendering;
  688. }
  689. set {
  690. use_compatible_text_rendering = value;
  691. }
  692. }
  693. #endif
  694. #endregion // Public Instance Properties
  695. #region Protected Instance Properties
  696. protected override Size DefaultSize {
  697. get {
  698. return base.DefaultSize;
  699. }
  700. }
  701. [Browsable(false)]
  702. [EditorBrowsable(EditorBrowsableState.Advanced)]
  703. [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
  704. protected virtual Type DefaultTabType {
  705. get {
  706. return typeof(PropertiesTab);
  707. }
  708. }
  709. protected bool DrawFlatToolbar {
  710. get {
  711. return (toolbar.Appearance == ToolBarAppearance.Flat);
  712. }
  713. set {
  714. if (value)
  715. toolbar.Appearance = ToolBarAppearance.Flat;
  716. else
  717. toolbar.Appearance = ToolBarAppearance.Normal;
  718. }
  719. }
  720. protected internal override bool ShowFocusCues {
  721. get {
  722. return base.ShowFocusCues;
  723. }
  724. }
  725. #endregion // Protected Instance Properties
  726. #region Public Instance Methods
  727. protected override void Dispose(bool val) {
  728. base.Dispose(val);
  729. }
  730. public void CollapseAllGridItems ()
  731. {
  732. GridEntry category = FindCategoryItem (selected_grid_item);
  733. if (category != null)
  734. SelectedGridItem = category;
  735. CollapseItemRecursive (root_grid_item);
  736. property_grid_view.UpdateView ();
  737. }
  738. private void CollapseItemRecursive (GridItem item)
  739. {
  740. if (item == null)
  741. return;
  742. foreach (GridItem child in item.GridItems) {
  743. CollapseItemRecursive (child);
  744. if (child.Expandable)
  745. child.Expanded = false;
  746. }
  747. }
  748. private GridEntry FindCategoryItem (GridEntry entry)
  749. {
  750. if (entry == null || (property_sort != PropertySort.Categorized &&
  751. property_sort != PropertySort.CategorizedAlphabetical))
  752. return null;
  753. if (entry.GridItemType == GridItemType.Category)
  754. return entry;
  755. GridEntry category = null;
  756. GridItem current = (GridItem)entry;
  757. while (category == null) {
  758. if (current.Parent != null && current.Parent.GridItemType == GridItemType.Category)
  759. category = (GridEntry) current.Parent;
  760. current = current.Parent;
  761. if (current == null)
  762. break;
  763. }
  764. return (GridEntry) category;
  765. }
  766. public void ExpandAllGridItems ()
  767. {
  768. ExpandItemRecursive (root_grid_item);
  769. property_grid_view.UpdateView ();
  770. }
  771. private void ExpandItemRecursive (GridItem item)
  772. {
  773. if (item == null)
  774. return;
  775. foreach (GridItem child in item.GridItems) {
  776. ExpandItemRecursive (child);
  777. if (child.Expandable)
  778. child.Expanded = true;
  779. }
  780. }
  781. public override void Refresh ()
  782. {
  783. base.Refresh ();
  784. property_grid_view.UpdateView ();
  785. }
  786. public void RefreshTabs (PropertyTabScope tabScope) {
  787. /*button = new ToolBarButton("C");
  788. button.ImageIndex = 0;
  789. this.toolbar.Buttons.Add(button);
  790. button = new ToolBarButton();
  791. button.ImageIndex = 0;
  792. button.Style = ToolBarButtonStyle.Separator;
  793. this.toolbar.Buttons.Add(button);
  794. foreach (PropertyTab tab in this.PropertyTabs)
  795. {
  796. int index = toolbar.ImageList.Images.Count;
  797. this.toolbar.ImageList.Images.Add(tab.Bitmap);
  798. button = new ToolBarButton();
  799. button.ImageIndex = index;
  800. this.toolbar.Buttons.Add(button);
  801. }*/
  802. }
  803. public void ResetSelectedProperty() {
  804. if (selected_grid_item == null)
  805. return;
  806. selected_grid_item.ResetValue ();
  807. }
  808. #endregion // Public Instance Methods
  809. #region Protected Instance Methods
  810. protected virtual PropertyTab CreatePropertyTab(Type tabType) {
  811. return (PropertyTab)Activator.CreateInstance(tabType);
  812. }
  813. [MonoTODO]
  814. protected void OnComComponentNameChanged(ComponentRenameEventArgs e)
  815. {
  816. ComponentRenameEventHandler eh = (ComponentRenameEventHandler)(Events [ComComponentNameChangedEvent]);
  817. if (eh != null)
  818. eh (this, e);
  819. }
  820. #if NET_2_0
  821. protected override void OnEnabledChanged (EventArgs e) {
  822. base.OnEnabledChanged (e);
  823. }
  824. #endif
  825. protected override void OnFontChanged(EventArgs e) {
  826. base.OnFontChanged (e);
  827. }
  828. protected override void OnGotFocus(EventArgs e) {
  829. base.OnGotFocus(e);
  830. }
  831. protected override void OnHandleCreated (EventArgs e) {
  832. base.OnHandleCreated (e);
  833. }
  834. protected override void OnHandleDestroyed (EventArgs e) {
  835. base.OnHandleDestroyed (e);
  836. }
  837. protected override void OnMouseDown (MouseEventArgs e) {
  838. base.OnMouseDown (e);
  839. }
  840. protected override void OnMouseMove (MouseEventArgs e) {
  841. base.OnMouseMove (e);
  842. }
  843. protected override void OnMouseUp (MouseEventArgs e) {
  844. base.OnMouseUp (e);
  845. }
  846. protected void OnNotifyPropertyValueUIItemsChanged(object sender, EventArgs e)
  847. {
  848. property_grid_view.UpdateView ();
  849. }
  850. protected override void OnPaint (PaintEventArgs pevent) {
  851. pevent.Graphics.FillRectangle(ThemeEngine.Current.ResPool.GetSolidBrush(BackColor), pevent.ClipRectangle);
  852. base.OnPaint (pevent);
  853. }
  854. #if NET_2_0
  855. protected virtual void OnPropertySortChanged(EventArgs e) {
  856. EventHandler eh = (EventHandler) Events [PropertySortChangedEvent];
  857. if (eh != null)
  858. eh (this, e);
  859. }
  860. #endif
  861. [MonoTODO]
  862. protected virtual void OnPropertyTabChanged (PropertyTabChangedEventArgs e) {
  863. throw new NotImplementedException();
  864. }
  865. protected virtual void OnPropertyValueChanged (PropertyValueChangedEventArgs e) {
  866. PropertyValueChangedEventHandler eh = (PropertyValueChangedEventHandler)(Events [PropertyValueChangedEvent]);
  867. if (eh != null)
  868. eh (this, e);
  869. }
  870. protected override void OnResize (EventArgs e) {
  871. base.OnResize (e);
  872. }
  873. protected virtual void OnSelectedGridItemChanged (SelectedGridItemChangedEventArgs e) {
  874. SelectedGridItemChangedEventHandler eh = (SelectedGridItemChangedEventHandler)(Events [SelectedGridItemChangedEvent]);
  875. if (eh != null)
  876. eh (this, e);
  877. }
  878. protected virtual void OnSelectedObjectsChanged (EventArgs e) {
  879. EventHandler eh = (EventHandler)(Events [SelectedObjectsChangedEvent]);
  880. if (eh != null)
  881. eh (this, e);
  882. }
  883. protected override void OnSystemColorsChanged (EventArgs e) {
  884. base.OnSystemColorsChanged (e);
  885. }
  886. protected override void OnVisibleChanged (EventArgs e) {
  887. base.OnVisibleChanged (e);
  888. }
  889. protected override bool ProcessDialogKey (Keys keyData) {
  890. return base.ProcessDialogKey (keyData);
  891. }
  892. #if NET_2_0
  893. [EditorBrowsable (EditorBrowsableState.Never)]
  894. #endif
  895. protected override void ScaleCore (float dx, float dy) {
  896. base.ScaleCore (dx, dy);
  897. }
  898. [MonoTODO]
  899. protected void ShowEventsButton(bool value) {
  900. throw new NotImplementedException();
  901. }
  902. protected override void WndProc (ref Message m) {
  903. base.WndProc (ref m);
  904. }
  905. #endregion
  906. #region Events
  907. static object PropertySortChangedEvent = new object ();
  908. static object PropertyTabChangedEvent = new object ();
  909. static object PropertyValueChangedEvent = new object ();
  910. static object SelectedGridItemChangedEvent = new object ();
  911. static object SelectedObjectsChangedEvent = new object ();
  912. public event EventHandler PropertySortChanged {
  913. add { Events.AddHandler (PropertySortChangedEvent, value); }
  914. remove { Events.RemoveHandler (PropertySortChangedEvent, value); }
  915. }
  916. public event PropertyTabChangedEventHandler PropertyTabChanged {
  917. add { Events.AddHandler (PropertyTabChangedEvent, value); }
  918. remove { Events.RemoveHandler (PropertyTabChangedEvent, value); }
  919. }
  920. public event PropertyValueChangedEventHandler PropertyValueChanged {
  921. add { Events.AddHandler (PropertyValueChangedEvent, value); }
  922. remove { Events.RemoveHandler (PropertyValueChangedEvent, value); }
  923. }
  924. public event SelectedGridItemChangedEventHandler SelectedGridItemChanged {
  925. add { Events.AddHandler (SelectedGridItemChangedEvent, value); }
  926. remove { Events.RemoveHandler (SelectedGridItemChangedEvent, value); }
  927. }
  928. public event EventHandler SelectedObjectsChanged {
  929. add { Events.AddHandler (SelectedObjectsChangedEvent, value); }
  930. remove { Events.RemoveHandler (SelectedObjectsChangedEvent, value); }
  931. }
  932. [Browsable(false)]
  933. [EditorBrowsable(EditorBrowsableState.Never)]
  934. public new event EventHandler BackgroundImageChanged {
  935. add { base.BackgroundImageChanged += value; }
  936. remove { base.BackgroundImageChanged -= value; }
  937. }
  938. #if NET_2_0
  939. [Browsable(false)]
  940. [EditorBrowsable(EditorBrowsableState.Never)]
  941. public new event EventHandler BackgroundImageLayoutChanged {
  942. add { base.BackgroundImageLayoutChanged += value; }
  943. remove { base.BackgroundImageLayoutChanged -= value; }
  944. }
  945. #endif
  946. [Browsable(false)]
  947. [EditorBrowsable(EditorBrowsableState.Never)]
  948. public new event EventHandler ForeColorChanged {
  949. add { base.ForeColorChanged += value; }
  950. remove { base.ForeColorChanged -= value; }
  951. }
  952. #if NET_2_0
  953. [EditorBrowsable(EditorBrowsableState.Advanced)]
  954. [Browsable(false)]
  955. public new event KeyEventHandler KeyDown {
  956. add { base.KeyDown += value; }
  957. remove { base.KeyDown -= value; }
  958. }
  959. [Browsable(false)]
  960. [EditorBrowsable(EditorBrowsableState.Advanced)]
  961. public new event KeyPressEventHandler KeyPress {
  962. add { base.KeyPress += value; }
  963. remove { base.KeyPress -= value; }
  964. }
  965. [EditorBrowsable(EditorBrowsableState.Advanced)]
  966. [Browsable(false)]
  967. public new event KeyEventHandler KeyUp {
  968. add { base.KeyUp += value; }
  969. remove { base.KeyUp -= value; }
  970. }
  971. [Browsable(false)]
  972. [EditorBrowsable(EditorBrowsableState.Advanced)]
  973. public new event MouseEventHandler MouseDown {
  974. add { base.MouseDown += value; }
  975. remove { base.MouseDown -= value; }
  976. }
  977. [EditorBrowsable(EditorBrowsableState.Advanced)]
  978. [Browsable(false)]
  979. public new event EventHandler MouseEnter {
  980. add { base.MouseEnter += value; }
  981. remove { base.MouseEnter -= value; }
  982. }
  983. [EditorBrowsable(EditorBrowsableState.Advanced)]
  984. [Browsable(false)]
  985. public new event EventHandler MouseLeave {
  986. add { base.MouseLeave += value; }
  987. remove { base.MouseLeave -= value; }
  988. }
  989. [EditorBrowsable(EditorBrowsableState.Advanced)]
  990. [Browsable(false)]
  991. public new event MouseEventHandler MouseMove {
  992. add { base.MouseMove += value; }
  993. remove { base.MouseMove -= value; }
  994. }
  995. [EditorBrowsable(EditorBrowsableState.Advanced)]
  996. [Browsable(false)]
  997. public new event MouseEventHandler MouseUp {
  998. add { base.MouseUp += value; }
  999. remove { base.MouseUp -= value; }
  1000. }
  1001. [Browsable(false)]
  1002. [EditorBrowsable(EditorBrowsableState.Never)]
  1003. public new event EventHandler PaddingChanged {
  1004. add { base.PaddingChanged += value; }
  1005. remove { base.PaddingChanged -= value; }
  1006. }
  1007. [Browsable(false)]
  1008. public new event EventHandler TextChanged {
  1009. add { base.TextChanged += value; }
  1010. remove { base.TextChanged -= value; }
  1011. }
  1012. #endif
  1013. #endregion
  1014. #region Com2Interop.IComPropertyBrowser Interface
  1015. [MonoTODO]
  1016. bool ComponentModel.Com2Interop.IComPropertyBrowser.InPropertySet {
  1017. get {
  1018. throw new NotImplementedException();
  1019. }
  1020. }
  1021. [MonoTODO]
  1022. void ComponentModel.Com2Interop.IComPropertyBrowser.DropDownDone() {
  1023. throw new NotImplementedException();
  1024. }
  1025. [MonoTODO]
  1026. bool ComponentModel.Com2Interop.IComPropertyBrowser.EnsurePendingChangesCommitted() {
  1027. throw new NotImplementedException();
  1028. }
  1029. [MonoTODO]
  1030. void ComponentModel.Com2Interop.IComPropertyBrowser.HandleF4() {
  1031. throw new NotImplementedException();
  1032. }
  1033. [MonoTODO]
  1034. void ComponentModel.Com2Interop.IComPropertyBrowser.LoadState(Microsoft.Win32.RegistryKey key) {
  1035. throw new NotImplementedException();
  1036. }
  1037. [MonoTODO]
  1038. void ComponentModel.Com2Interop.IComPropertyBrowser.SaveState(Microsoft.Win32.RegistryKey key) {
  1039. throw new NotImplementedException();
  1040. }
  1041. static object ComComponentNameChangedEvent = new object ();
  1042. event ComponentRenameEventHandler ComponentModel.Com2Interop.IComPropertyBrowser.ComComponentNameChanged {
  1043. add { Events.AddHandler (ComComponentNameChangedEvent, value); }
  1044. remove { Events.RemoveHandler (ComComponentNameChangedEvent, value); }
  1045. }
  1046. #endregion // Com2Interop.IComPropertyBrowser Interface
  1047. #region PropertyTabCollection Class
  1048. public class PropertyTabCollection : ICollection, IEnumerable {
  1049. System.Collections.ArrayList list;
  1050. #region Private Constructors
  1051. internal PropertyTabCollection() {
  1052. list = new ArrayList();
  1053. }
  1054. #endregion // Private Constructors
  1055. public PropertyTab this[int index] {
  1056. get {
  1057. return (PropertyTab)list[index];
  1058. }
  1059. }
  1060. #region ICollection Members
  1061. bool ICollection.IsSynchronized {
  1062. get {
  1063. return list.IsSynchronized;
  1064. }
  1065. }
  1066. void ICollection.CopyTo(Array array, int index) {
  1067. list.CopyTo(array, index);
  1068. }
  1069. object ICollection.SyncRoot {
  1070. get {
  1071. return list.SyncRoot;
  1072. }
  1073. }
  1074. #endregion
  1075. #region IEnumerable Members
  1076. public IEnumerator GetEnumerator() {
  1077. return list.GetEnumerator();
  1078. }
  1079. #endregion
  1080. #region ICollection Members
  1081. public int Count {
  1082. get {
  1083. return list.Count;
  1084. }
  1085. }
  1086. #endregion
  1087. #region Public Instance Methods
  1088. public void AddTabType(System.Type propertyTabType) {
  1089. list.Add(Activator.CreateInstance(propertyTabType));
  1090. }
  1091. [MonoTODO]
  1092. public void AddTabType(System.Type propertyTabType,
  1093. System.ComponentModel.PropertyTabScope tabScope) {
  1094. AddTabType(propertyTabType);
  1095. }
  1096. [MonoTODO]
  1097. public void Clear(System.ComponentModel.PropertyTabScope tabScope) {
  1098. throw new NotImplementedException();
  1099. }
  1100. [MonoTODO]
  1101. public void RemoveTabType(System.Type propertyTabType) {
  1102. throw new NotImplementedException();
  1103. }
  1104. #endregion
  1105. }
  1106. #endregion // PropertyTabCollection Class
  1107. #region Private Helper Methods
  1108. private GridItem FindFirstPropertyItem (GridItem root)
  1109. {
  1110. if (root.GridItemType == GridItemType.Property)
  1111. return root;
  1112. foreach (GridItem item in root.GridItems) {
  1113. GridItem subitem = FindFirstPropertyItem (item);
  1114. if (subitem != null)
  1115. return subitem;
  1116. }
  1117. return null;
  1118. }
  1119. // TODO: Should use the current tab's GetDefaultProperty and the current
  1120. // code should be PropertyTab specific
  1121. //
  1122. private GridEntry GetDefaultPropertyItem (GridEntry rootItem)
  1123. {
  1124. if (rootItem == null || rootItem.GridItems.Count == 0)
  1125. return null;
  1126. object[] propertyOwners = rootItem.Values;
  1127. if (propertyOwners == null || propertyOwners.Length == 0 || propertyOwners[0] == null)
  1128. return null;
  1129. //return (GridEntry) FindFirstItem (rootItem);
  1130. GridItem defaultSelected = null;
  1131. if (propertyOwners.Length > 1)
  1132. defaultSelected = rootItem.GridItems[0];
  1133. else {
  1134. PropertyDescriptor defaultProperty = null;
  1135. ICustomTypeDescriptor customTypeDescriptor = propertyOwners[0] as ICustomTypeDescriptor;
  1136. if (customTypeDescriptor != null) // try 1: ICustomTypeDescriptor
  1137. defaultProperty = customTypeDescriptor.GetDefaultProperty ();
  1138. if (defaultProperty == null) // try 2: TypeDescriptor
  1139. defaultProperty = TypeDescriptor.GetDefaultProperty (propertyOwners[0]);
  1140. if (defaultProperty != null)
  1141. defaultSelected = FindItem (defaultProperty.Name, rootItem);
  1142. if (defaultSelected == null)
  1143. defaultSelected = FindFirstPropertyItem (rootItem);
  1144. }
  1145. return defaultSelected as GridEntry;
  1146. }
  1147. private GridEntry FindItem (string name, GridEntry rootItem)
  1148. {
  1149. if (rootItem == null || name == null)
  1150. return null;
  1151. if (property_sort == PropertySort.Alphabetical || property_sort == PropertySort.NoSort) {
  1152. foreach (GridItem item in rootItem.GridItems) {
  1153. if (item.Label == name) {
  1154. return (GridEntry)item;
  1155. }
  1156. }
  1157. } else if (property_sort == PropertySort.Categorized ||
  1158. property_sort == PropertySort.CategorizedAlphabetical) {
  1159. foreach (GridItem categoryItem in rootItem.GridItems) {
  1160. foreach (GridItem item in categoryItem.GridItems) {
  1161. if (item.Label == name) {
  1162. return (GridEntry)item;
  1163. }
  1164. }
  1165. }
  1166. }
  1167. return null;
  1168. }
  1169. #if NET_2_0
  1170. private void toolbar_ButtonClick (object sender, ToolStripItemClickedEventArgs e)
  1171. {
  1172. toolbar_Clicked (e.ClickedItem as PropertyToolBarButton);
  1173. }
  1174. #else
  1175. private void toolbar_ButtonClick (object sender, ToolBarButtonClickEventArgs e)
  1176. {
  1177. toolbar_Clicked (e.Button as PropertyToolBarButton);
  1178. }
  1179. #endif
  1180. private void toolbar_Clicked (PropertyToolBarButton button)
  1181. {
  1182. if (button == null)
  1183. return;
  1184. if (button == alphabetic_toolbarbutton) {
  1185. this.PropertySort = PropertySort.Alphabetical;
  1186. } else if (button == categorized_toolbarbutton) {
  1187. if ((this.PropertySort & PropertySort.Categorized) == 0)
  1188. this.PropertySort = PropertySort.CategorizedAlphabetical;
  1189. else
  1190. UpdateToolBarButtons ();
  1191. }
  1192. }
  1193. private void UpdateToolBarButtons ()
  1194. {
  1195. if ((PropertySort & PropertySort.Categorized) != 0) {
  1196. categorized_toolbarbutton.Pushed = true;
  1197. alphabetic_toolbarbutton.Pushed = false;
  1198. } else if ((PropertySort & PropertySort.Alphabetical) != 0) {
  1199. categorized_toolbarbutton.Pushed = false;
  1200. alphabetic_toolbarbutton.Pushed = true;
  1201. } else {
  1202. categorized_toolbarbutton.Pushed = false;
  1203. alphabetic_toolbarbutton.Pushed = false;
  1204. }
  1205. }
  1206. private void OnResetPropertyClick (object sender, EventArgs e)
  1207. {
  1208. ResetSelectedProperty();
  1209. }
  1210. private void OnDescriptionClick (object sender, EventArgs e)
  1211. {
  1212. this.HelpVisible = !this.HelpVisible;
  1213. description_menuitem.Checked = this.HelpVisible;
  1214. }
  1215. private void PopulateGrid (object[] objects) {
  1216. if (objects.Length > 0) {
  1217. root_grid_item = new RootGridEntry (this, objects);
  1218. PopulateRootGridItems (root_grid_item, objects, GetMergedPropertyNames (objects));
  1219. } else {
  1220. root_grid_item = null;
  1221. }
  1222. }
  1223. private bool IsPropertyVisible (PropertyDescriptor property, bool mergable)
  1224. {
  1225. if (property == null)
  1226. return false;
  1227. if (!property.IsBrowsable)
  1228. return false;
  1229. if (mergable) {
  1230. MergablePropertyAttribute attrib = property.Attributes [typeof (MergablePropertyAttribute)] as MergablePropertyAttribute;
  1231. if (attrib != null && !attrib.AllowMerge)
  1232. return false;
  1233. }
  1234. EditorBrowsableAttribute browsable = property.Attributes [typeof (EditorBrowsableAttribute)] as EditorBrowsableAttribute;
  1235. if (browsable != null && (browsable.State == EditorBrowsableState.Advanced || browsable.State == EditorBrowsableState.Never)) {
  1236. return false;
  1237. }
  1238. return true;
  1239. }
  1240. private string[] GetMergedPropertyNames (object [] objects)
  1241. {
  1242. ArrayList intersection = null;
  1243. for (int i = 0; i < objects.Length; i ++) {
  1244. if (objects [i] == null)
  1245. continue;
  1246. PropertyDescriptorCollection properties = GetProperties (objects[i]);
  1247. ArrayList new_intersection = new ArrayList ();
  1248. foreach (PropertyDescriptor currentProperty in (i == 0 ? (ICollection)properties : (ICollection)intersection)) {
  1249. PropertyDescriptor matchingProperty = (i == 0 ? currentProperty : properties [currentProperty.Name]);
  1250. if (!IsPropertyVisible (matchingProperty, objects.Length > 1))
  1251. continue;
  1252. if (matchingProperty.PropertyType == currentProperty.PropertyType)
  1253. new_intersection.Add (matchingProperty);
  1254. }
  1255. intersection = new_intersection;
  1256. }
  1257. string[] propertyNames = new string [intersection.Count];
  1258. for (int i=0; i < intersection.Count; i++)
  1259. propertyNames[i] = ((PropertyDescriptor)intersection[i]).Name;
  1260. return propertyNames;
  1261. }
  1262. private PropertyDescriptor GetPropertyDescriptor (object propertyOwner, string propertyName)
  1263. {
  1264. if (propertyOwner == null || propertyName == null)
  1265. return null;
  1266. PropertyDescriptorCollection properties = GetProperties (propertyOwner);
  1267. if (properties != null)
  1268. return properties[propertyName];
  1269. return null;
  1270. }
  1271. // TODO: Should use the current tab's GetProperties and the current code
  1272. // should be PropertyTab specific
  1273. //
  1274. private PropertyDescriptorCollection GetProperties (object propertyOwner)
  1275. {
  1276. if (propertyOwner == null)
  1277. return null;
  1278. PropertyDescriptorCollection properties = null;
  1279. ICustomTypeDescriptor customTypeDescriptor = propertyOwner as ICustomTypeDescriptor;
  1280. if (customTypeDescriptor != null) // try 1: ICustomTypeDescriptor
  1281. properties = customTypeDescriptor.GetProperties ();
  1282. if (properties == null) { // try 2: Converter with PropertiesSupported
  1283. TypeConverter converter = TypeDescriptor.GetConverter (propertyOwner);
  1284. if (converter.GetPropertiesSupported ())
  1285. properties = converter.GetProperties (propertyOwner);
  1286. }
  1287. if (properties == null) // try 3: TypeDescriptor
  1288. properties = TypeDescriptor.GetProperties (propertyOwner);
  1289. return properties;
  1290. }
  1291. private void PopulateRootGridItems (GridEntry rootItem, object[] propertyOwners, string[] propertyNames)
  1292. {
  1293. if (propertyOwners == null || propertyNames == null)
  1294. return;
  1295. bool categorized = property_sort == PropertySort.Categorized ||
  1296. property_sort == PropertySort.CategorizedAlphabetical;
  1297. rootItem.GridItems.Clear ();
  1298. foreach (string propertyName in propertyNames) {
  1299. GridEntry item = null;
  1300. PropertyDescriptor[] properties = new PropertyDescriptor[propertyOwners.Length];
  1301. for (int i=0; i < propertyOwners.Length; i++)
  1302. properties[i] = GetPropertyDescriptor (propertyOwners[i], propertyName);
  1303. if (categorized) {
  1304. string categoryName = null;
  1305. foreach (PropertyDescriptor property in properties) {
  1306. categoryName = property.Category;
  1307. if (categoryName != null)
  1308. break;
  1309. }
  1310. if (categoryName == null)
  1311. categoryName = UNCATEGORIZED_CATEGORY_LABEL;
  1312. GridEntry category = (GridEntry)root_grid_item.GridItems[categoryName];
  1313. if (category == null) {
  1314. category = new CategoryGridEntry (this, categoryName, rootItem);
  1315. category.Expanded = true;
  1316. rootItem.GridItems.Add (category);
  1317. }
  1318. item = new GridEntry (this, properties, category);
  1319. category.GridItems.Add (item);
  1320. } else {
  1321. item = new GridEntry (this, properties, rootItem);
  1322. rootItem.GridItems.Add (item);
  1323. }
  1324. PopulateSubGridItems (item);
  1325. }
  1326. }
  1327. private void PopulateSubGridItems (GridEntry parentItem)
  1328. {
  1329. parentItem.GridItems.Clear ();
  1330. if (!IsExpandable (parentItem))
  1331. return;
  1332. object[] propertyOwners = parentItem.Values;
  1333. if (propertyOwners == null)
  1334. return;
  1335. PropertyDescriptorCollection propertiesCollection = GetProperties (propertyOwners[0]);
  1336. if (propertiesCollection == null)
  1337. return;
  1338. foreach (PropertyDescriptor property in propertiesCollection) {
  1339. string propertyName = property.Name;
  1340. PropertyDescriptor[] properties = new PropertyDescriptor[propertyOwners.Length];
  1341. for (int i=0; i < propertyOwners.Length; i++)
  1342. properties[i] = GetPropertyDescriptor (propertyOwners[i], propertyName);
  1343. GridEntry item = new GridEntry (this, properties, parentItem);
  1344. parentItem.GridItems.Add (item);
  1345. if (IsExpandable (item))
  1346. PopulateSubGridItems (item);
  1347. }
  1348. }
  1349. private bool IsExpandable (GridEntry item)
  1350. {
  1351. if (item == null || item.PropertyDescriptor == null ||
  1352. item.PropertyDescriptor.Converter == null)
  1353. return false;
  1354. else if (!item.PropertyDescriptor.Converter.GetPropertiesSupported () &&
  1355. !item.PropertyDescriptor.Attributes.Contains (
  1356. DesignerSerializationVisibilityAttribute.Content))
  1357. return false;
  1358. return true;
  1359. }
  1360. private void UpdateSortLayout (GridEntry rootItem)
  1361. {
  1362. if (rootItem == null)
  1363. return;
  1364. GridItemCollection reordered = new GridItemCollection ();
  1365. if (property_sort == PropertySort.Alphabetical || property_sort == PropertySort.NoSort) {
  1366. foreach (GridItem item in rootItem.GridItems) {
  1367. if (item.GridItemType == GridItemType.Category) {
  1368. foreach (GridItem categoryChild in item.GridItems) {
  1369. reordered.Add (categoryChild);
  1370. ((GridEntry)categoryChild).SetParent (rootItem);
  1371. }
  1372. } else {
  1373. reordered.Add (item);
  1374. }
  1375. }
  1376. } else if (property_sort == PropertySort.Categorized ||
  1377. property_sort == PropertySort.CategorizedAlphabetical) {
  1378. GridItemCollection categories = new GridItemCollection ();
  1379. foreach (GridItem item in rootItem.GridItems) {
  1380. if (item.GridItemType == GridItemType.Category) {
  1381. categories.Add (item);
  1382. continue;
  1383. }
  1384. string categoryName = item.PropertyDescriptor.Category;
  1385. if (categoryName == null)
  1386. categoryName = UNCATEGORIZED_CATEGORY_LABEL;
  1387. GridItem category_item = rootItem.GridItems [categoryName];
  1388. if (category_item == null)
  1389. category_item = categories [categoryName];
  1390. if (category_item == null) {
  1391. // Create category grid items if they already don't
  1392. category_item = new CategoryGridEntry (this, categoryName, rootItem);
  1393. category_item.Expanded = true;
  1394. categories.Add (category_item);
  1395. }
  1396. category_item.GridItems.Add (item);
  1397. ((GridEntry)item).SetParent (category_item);
  1398. }
  1399. reordered.AddRange (categories);
  1400. }
  1401. rootItem.GridItems.Clear ();
  1402. rootItem.GridItems.AddRange (reordered);
  1403. }
  1404. private void help_panel_Paint(object sender, PaintEventArgs e) {
  1405. e.Graphics.FillRectangle(ThemeEngine.Current.ResPool.GetSolidBrush(help_panel.BackColor), help_panel.ClientRectangle );
  1406. e.Graphics.DrawRectangle(SystemPens.ControlDark, 0,0,help_panel.Width-1,help_panel.Height-1 );
  1407. }
  1408. #endregion // Private Helper Methods
  1409. #region Internal helper classes
  1410. // as we can not change the color for BorderStyle.FixedSingle and we need the correct
  1411. // ClientRectangle so that the ScrollBar doesn't draw over the border we need this class
  1412. internal class BorderHelperControl : Control {
  1413. public BorderHelperControl ()
  1414. {
  1415. BackColor = ThemeEngine.Current.ColorWindow;
  1416. }
  1417. protected override void OnPaint (PaintEventArgs e)
  1418. {
  1419. e.Graphics.DrawRectangle (SystemPens.ControlDark, 0 , 0 , Width - 1, Height - 1);
  1420. base.OnPaint (e);
  1421. }
  1422. protected override void OnSizeChanged (EventArgs e)
  1423. {
  1424. if (Controls.Count == 1) {
  1425. Control control = Controls [0];
  1426. if (control.Location.X != 1 || control.Location.Y != 1)
  1427. control.Location = new Point (1, 1);
  1428. control.Width = ClientRectangle.Width - 2;
  1429. control.Height = ClientRectangle.Height - 2;
  1430. }
  1431. base.OnSizeChanged (e);
  1432. }
  1433. }
  1434. internal class PropertyToolBarButton :
  1435. #if NET_2_0
  1436. ToolStripButton
  1437. #else
  1438. ToolBarButton
  1439. #endif
  1440. {
  1441. #if NET_2_0
  1442. public bool Pushed {
  1443. get { return base.Checked; }
  1444. set { base.Checked = value; }
  1445. }
  1446. public ToolBarButtonStyle Style {
  1447. get { return ToolBarButtonStyle.PushButton; }
  1448. set { }
  1449. }
  1450. #endif
  1451. }
  1452. // needed! this little helper makes it possible to draw a different toolbar border
  1453. // and toolbar backcolor in ThemeWin32Classic
  1454. internal class PropertyToolBar :
  1455. #if NET_2_0
  1456. ToolStrip
  1457. #else
  1458. ToolBar
  1459. #endif
  1460. {
  1461. #if NET_2_0
  1462. bool flat;
  1463. #endif
  1464. public PropertyToolBar ()
  1465. {
  1466. SetStyle (ControlStyles.ResizeRedraw, true);
  1467. #if NET_2_0
  1468. GripStyle = ToolStripGripStyle.Hidden;
  1469. #endif
  1470. }
  1471. #if NET_2_0
  1472. public bool ShowToolTips {
  1473. get { return base.ShowItemToolTips; }
  1474. set { base.ShowItemToolTips = value; }
  1475. }
  1476. public ToolBarAppearance Appearance {
  1477. get { return flat ? ToolBarAppearance.Flat : ToolBarAppearance.Normal; }
  1478. set {
  1479. if (value == Appearance)
  1480. return;
  1481. switch (value) {
  1482. case ToolBarAppearance.Flat:
  1483. Renderer = new ToolStripSystemRenderer ();
  1484. break;
  1485. case ToolBarAppearance.Normal:
  1486. ProfessionalColorTable table = new ProfessionalColorTable ();
  1487. table.UseSystemColors = true;
  1488. Renderer = new ToolStripProfessionalRenderer (table);
  1489. break;
  1490. }
  1491. }
  1492. }
  1493. #endif
  1494. }
  1495. [MonoTODO ("not sure what this class does, but it's listed as a type converter for a property in this class, and this causes problems if it's not present")]
  1496. internal class SelectedObjectConverter : TypeConverter
  1497. {
  1498. }
  1499. #endregion
  1500. }
  1501. }