DataList.cs 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129
  1. //
  2. // System.Web.UI.WebControls.DataList.cs
  3. //
  4. // Author:
  5. // Sebastien Pouliot <[email protected]>
  6. //
  7. // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
  8. //
  9. // Permission is hereby granted, free of charge, to any person obtaining
  10. // a copy of this software and associated documentation files (the
  11. // "Software"), to deal in the Software without restriction, including
  12. // without limitation the rights to use, copy, modify, merge, publish,
  13. // distribute, sublicense, and/or sell copies of the Software, and to
  14. // permit persons to whom the Software is furnished to do so, subject to
  15. // the following conditions:
  16. //
  17. // The above copyright notice and this permission notice shall be
  18. // included in all copies or substantial portions of the Software.
  19. //
  20. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  21. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  22. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  23. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  24. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  25. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  26. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  27. //
  28. using System.Collections;
  29. using System.ComponentModel;
  30. using System.Globalization;
  31. using System.Security.Permissions;
  32. using System.Web.Util;
  33. namespace System.Web.UI.WebControls {
  34. // CAS
  35. [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
  36. [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
  37. // attributes
  38. [Designer ("System.Web.UI.Design.WebControls.DataListDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
  39. #if NET_2_0
  40. [ControlValueProperty ("SelectedValue")]
  41. [Editor ("System.Web.UI.Design.WebControls.DataListComponentEditor, " + Consts.AssemblySystem_Design, "System.ComponentModel.ComponentEditor, " + Consts.AssemblySystem)]
  42. #else
  43. [Editor ("System.Web.UI.Design.WebControls.DataListComponentEditor, " + Consts.AssemblySystem_Design, typeof (System.ComponentModel.ComponentEditor))]
  44. #endif
  45. public class DataList : BaseDataList, INamingContainer, IRepeatInfoUser {
  46. public const string CancelCommandName = "Cancel";
  47. public const string DeleteCommandName = "Delete";
  48. public const string EditCommandName = "Edit";
  49. public const string SelectCommandName = "Select";
  50. public const string UpdateCommandName = "Update";
  51. private static readonly object cancelCommandEvent = new object ();
  52. private static readonly object deleteCommandEvent = new object ();
  53. private static readonly object editCommandEvent = new object ();
  54. private static readonly object itemCommandEvent = new object ();
  55. private static readonly object itemCreatedEvent = new object ();
  56. private static readonly object itemDataBoundEvent = new object ();
  57. private static readonly object updateCommandEvent = new object ();
  58. private TableItemStyle alternatingItemStyle;
  59. private TableItemStyle editItemStyle;
  60. private TableItemStyle footerStyle;
  61. private TableItemStyle headerStyle;
  62. private TableItemStyle itemStyle;
  63. private TableItemStyle selectedItemStyle;
  64. private TableItemStyle separatorStyle;
  65. private ITemplate alternatingItemTemplate;
  66. private ITemplate editItemTemplate;
  67. private ITemplate footerTemplate;
  68. private ITemplate headerTemplate;
  69. private ITemplate itemTemplate;
  70. private ITemplate selectedItemTemplate;
  71. private ITemplate separatorTemplate;
  72. private DataListItemCollection items;
  73. private ArrayList list;
  74. private int idx;
  75. #if NET_2_0
  76. private int editIndex;
  77. private int selectedIndex;
  78. public DataList ()
  79. {
  80. editIndex = -1;
  81. selectedIndex = -1;
  82. idx = -1;
  83. }
  84. #else
  85. public DataList ()
  86. {
  87. idx = -1;
  88. }
  89. #endif
  90. [DefaultValue (null)]
  91. [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
  92. [NotifyParentProperty (true)]
  93. [PersistenceMode (PersistenceMode.InnerProperty)]
  94. [WebSysDescription ("")]
  95. [WebCategory ("Style")]
  96. public virtual TableItemStyle AlternatingItemStyle {
  97. get {
  98. if (alternatingItemStyle == null) {
  99. alternatingItemStyle = new TableItemStyle ();
  100. if (IsTrackingViewState) {
  101. alternatingItemStyle.TrackViewState ();
  102. }
  103. }
  104. return alternatingItemStyle;
  105. }
  106. }
  107. [Browsable (false)]
  108. [DefaultValue (null)]
  109. [TemplateContainer (typeof (DataListItem))]
  110. [PersistenceMode (PersistenceMode.InnerProperty)]
  111. [WebSysDescription ("")]
  112. [WebCategory ("Style")]
  113. public virtual ITemplate AlternatingItemTemplate {
  114. get { return alternatingItemTemplate; }
  115. set { alternatingItemTemplate = value; }
  116. }
  117. [DefaultValue (-1)]
  118. [WebSysDescription ("")]
  119. [WebCategory ("Misc")]
  120. public virtual int EditItemIndex {
  121. get {
  122. object o = ViewState ["EditItemIndex"];
  123. return (o == null) ? -1 : (int) o;
  124. }
  125. set {
  126. if (value < -1)
  127. throw new ArgumentOutOfRangeException ("EditItemIndex", "< -1");
  128. ViewState ["EditItemIndex"] = value;
  129. }
  130. }
  131. [DefaultValue (null)]
  132. [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
  133. [NotifyParentProperty (true)]
  134. [PersistenceMode (PersistenceMode.InnerProperty)]
  135. [WebSysDescription ("")]
  136. [WebCategory ("Style")]
  137. public virtual TableItemStyle EditItemStyle {
  138. get {
  139. if (editItemStyle == null) {
  140. editItemStyle = new TableItemStyle ();
  141. if (IsTrackingViewState) {
  142. editItemStyle.TrackViewState ();
  143. }
  144. }
  145. return editItemStyle;
  146. }
  147. }
  148. [Browsable (false)]
  149. [DefaultValue (null)]
  150. [TemplateContainer (typeof (DataListItem))]
  151. [PersistenceMode (PersistenceMode.InnerProperty)]
  152. [WebSysDescription ("")]
  153. [WebCategory ("Style")]
  154. public virtual ITemplate EditItemTemplate {
  155. get { return editItemTemplate; }
  156. set { editItemTemplate = value; }
  157. }
  158. [DefaultValue (false)]
  159. [WebSysDescription ("")]
  160. [WebCategory ("Misc")]
  161. public virtual bool ExtractTemplateRows {
  162. get {
  163. object o = ViewState ["ExtractTemplateRows"];
  164. return (o == null) ? false : (bool) o;
  165. }
  166. set { ViewState ["ExtractTemplateRows"] = value; }
  167. }
  168. [DefaultValue (null)]
  169. [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
  170. [NotifyParentProperty (true)]
  171. [PersistenceMode (PersistenceMode.InnerProperty)]
  172. [WebSysDescription ("")]
  173. [WebCategory ("Style")]
  174. public virtual TableItemStyle FooterStyle {
  175. get {
  176. if (footerStyle == null) {
  177. footerStyle = new TableItemStyle ();
  178. if (IsTrackingViewState) {
  179. footerStyle.TrackViewState ();
  180. }
  181. }
  182. return footerStyle;
  183. }
  184. }
  185. [Browsable (false)]
  186. [DefaultValue (null)]
  187. [TemplateContainer (typeof (DataListItem))]
  188. [PersistenceMode (PersistenceMode.InnerProperty)]
  189. [WebSysDescription ("")]
  190. [WebCategory ("Style")]
  191. public virtual ITemplate FooterTemplate {
  192. get { return footerTemplate; }
  193. set { footerTemplate = value; }
  194. }
  195. // yes! they do NOT match in fx1.1
  196. [DefaultValue (GridLines.None)]
  197. public override GridLines GridLines {
  198. get {
  199. if (!ControlStyleCreated) {
  200. #if NET_2_0
  201. return GridLines.None;
  202. #else
  203. return GridLines.Both;
  204. #endif
  205. }
  206. return TableStyle.GridLines;
  207. }
  208. set { TableStyle.GridLines = value; }
  209. }
  210. [DefaultValue (null)]
  211. [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
  212. [NotifyParentProperty (true)]
  213. [PersistenceMode (PersistenceMode.InnerProperty)]
  214. [WebSysDescription ("")]
  215. [WebCategory ("Style")]
  216. public virtual TableItemStyle HeaderStyle {
  217. get {
  218. if (headerStyle == null) {
  219. headerStyle = new TableItemStyle ();
  220. if (IsTrackingViewState) {
  221. headerStyle.TrackViewState ();
  222. }
  223. }
  224. return headerStyle;
  225. }
  226. }
  227. [Browsable (false)]
  228. [DefaultValue (null)]
  229. [TemplateContainer (typeof (DataListItem))]
  230. [PersistenceMode (PersistenceMode.InnerProperty)]
  231. [WebSysDescription ("")]
  232. [WebCategory ("Style")]
  233. public virtual ITemplate HeaderTemplate {
  234. get { return headerTemplate; }
  235. set { headerTemplate = value; }
  236. }
  237. [Browsable (false)]
  238. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  239. [WebSysDescription ("")]
  240. [WebCategory ("Style")]
  241. public virtual DataListItemCollection Items {
  242. get {
  243. if (items == null)
  244. items = new DataListItemCollection (ItemList);
  245. return items;
  246. }
  247. }
  248. [DefaultValue (null)]
  249. [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
  250. [NotifyParentProperty (true)]
  251. [PersistenceMode (PersistenceMode.InnerProperty)]
  252. [WebSysDescription ("")]
  253. [WebCategory ("Style")]
  254. public virtual TableItemStyle ItemStyle {
  255. get {
  256. if (itemStyle == null) {
  257. itemStyle = new TableItemStyle ();
  258. if (IsTrackingViewState) {
  259. itemStyle.TrackViewState ();
  260. }
  261. }
  262. return itemStyle;
  263. }
  264. }
  265. [Browsable (false)]
  266. [DefaultValue (null)]
  267. [TemplateContainer (typeof (DataListItem))]
  268. [PersistenceMode (PersistenceMode.InnerProperty)]
  269. [WebSysDescription ("")]
  270. [WebCategory ("Style")]
  271. public virtual ITemplate ItemTemplate {
  272. get { return itemTemplate; }
  273. set { itemTemplate = value; }
  274. }
  275. #if ONLY_1_1
  276. [Bindable (true)]
  277. #endif
  278. [DefaultValue (0)]
  279. [WebSysDescription ("")]
  280. [WebCategory ("Layout")]
  281. public virtual int RepeatColumns {
  282. get {
  283. object o = ViewState ["RepeatColumns"];
  284. return (o == null) ? 0 : (int) o;
  285. }
  286. set {
  287. if (value < 0)
  288. throw new ArgumentOutOfRangeException ("value", "RepeatColumns value has to be 0 for 'not set' or > 0.");
  289. ViewState ["RepeatColumns"] = value;
  290. }
  291. }
  292. #if ONLY_1_1
  293. [Bindable (true)]
  294. #endif
  295. [DefaultValue (RepeatDirection.Vertical)]
  296. [WebSysDescription ("")]
  297. [WebCategory ("Layout")]
  298. public virtual RepeatDirection RepeatDirection {
  299. get {
  300. object o = ViewState ["RepeatDirection"];
  301. return (o == null) ? RepeatDirection.Vertical : (RepeatDirection) o;
  302. }
  303. set { ViewState ["RepeatDirection"] = value; }
  304. }
  305. #if ONLY_1_1
  306. [Bindable (true)]
  307. #endif
  308. [DefaultValue (RepeatLayout.Table)]
  309. [WebSysDescription ("")]
  310. [WebCategory ("Layout")]
  311. public virtual RepeatLayout RepeatLayout {
  312. get {
  313. object o = ViewState ["RepeatLayout"];
  314. return (o == null) ? RepeatLayout.Table : (RepeatLayout) o;
  315. }
  316. set { ViewState ["RepeatLayout"] = value; }
  317. }
  318. [Bindable (true)]
  319. [DefaultValue (-1)]
  320. [WebSysDescription ("")]
  321. [WebCategory ("Layout")]
  322. public virtual int SelectedIndex {
  323. get {
  324. object o = ViewState ["SelectedIndex"];
  325. return (o == null) ? -1 : (int) o;
  326. }
  327. set {
  328. if (value < -1)
  329. throw new ArgumentOutOfRangeException ("SelectedIndex", "< -1");
  330. ViewState ["SelectedIndex"] = value;
  331. }
  332. }
  333. [Browsable (false)]
  334. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  335. [WebSysDescription ("")]
  336. [WebCategory ("Layout")]
  337. public virtual DataListItem SelectedItem {
  338. get {
  339. if (SelectedIndex < 0)
  340. return null;
  341. if (SelectedIndex >= Items.Count)
  342. throw new ArgumentOutOfRangeException ("SelectedItem", ">= Items.Count");
  343. return items [SelectedIndex];
  344. }
  345. }
  346. [DefaultValue (null)]
  347. [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
  348. [NotifyParentProperty (true)]
  349. [PersistenceMode (PersistenceMode.InnerProperty)]
  350. [WebSysDescription ("")]
  351. [WebCategory ("Style")]
  352. public virtual TableItemStyle SelectedItemStyle {
  353. get {
  354. if (selectedItemStyle == null) {
  355. selectedItemStyle = new TableItemStyle ();
  356. if (IsTrackingViewState) {
  357. selectedItemStyle.TrackViewState ();
  358. }
  359. }
  360. return selectedItemStyle;
  361. }
  362. }
  363. [Browsable (false)]
  364. [DefaultValue (null)]
  365. [TemplateContainer (typeof (DataListItem))]
  366. [PersistenceMode (PersistenceMode.InnerProperty)]
  367. [WebSysDescription ("")]
  368. [WebCategory ("Style")]
  369. public virtual ITemplate SelectedItemTemplate {
  370. get { return selectedItemTemplate; }
  371. set { selectedItemTemplate = value; }
  372. }
  373. [DefaultValue (null)]
  374. [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
  375. [NotifyParentProperty (true)]
  376. [PersistenceMode (PersistenceMode.InnerProperty)]
  377. [WebSysDescription ("")]
  378. [WebCategory ("Style")]
  379. public virtual TableItemStyle SeparatorStyle {
  380. get {
  381. if (separatorStyle == null) {
  382. separatorStyle = new TableItemStyle ();
  383. if (IsTrackingViewState) {
  384. separatorStyle.TrackViewState ();
  385. }
  386. }
  387. return separatorStyle;
  388. }
  389. }
  390. [Browsable (false)]
  391. [DefaultValue (null)]
  392. [TemplateContainer (typeof (DataListItem))]
  393. [PersistenceMode (PersistenceMode.InnerProperty)]
  394. [WebSysDescription ("")]
  395. [WebCategory ("Style")]
  396. public virtual ITemplate SeparatorTemplate {
  397. get { return separatorTemplate; }
  398. set { separatorTemplate = value; }
  399. }
  400. #if ONLY_1_1
  401. [Bindable (true)]
  402. #endif
  403. [DefaultValue (true)]
  404. [WebSysDescription ("")]
  405. [WebCategory ("Appearance")]
  406. public virtual bool ShowFooter {
  407. get {
  408. object o = ViewState ["ShowFooter"];
  409. return (o == null) ? true : (bool) o;
  410. }
  411. set { ViewState ["ShowFooter"] = value; }
  412. }
  413. #if ONLY_1_1
  414. [Bindable (true)]
  415. #endif
  416. [DefaultValue (true)]
  417. [WebSysDescription ("")]
  418. [WebCategory ("Appearance")]
  419. public virtual bool ShowHeader {
  420. get {
  421. object o = ViewState ["ShowHeader"];
  422. return (o == null) ? true : (bool) o;
  423. }
  424. set { ViewState ["ShowHeader"] = value; }
  425. }
  426. #if NET_2_0
  427. [MonoTODO ("incomplete")]
  428. [Browsable (false)]
  429. public object SelectedValue {
  430. get {
  431. if (DataKeyField.Length == 0)
  432. throw new InvalidOperationException (Locale.GetText ("No DataKeyField present."));
  433. if ((SelectedIndex >= 0) && (selectedIndex < DataKeys.Count)) {
  434. return DataKeys [selectedIndex];
  435. }
  436. return null;
  437. }
  438. }
  439. protected override HtmlTextWriterTag TagKey {
  440. get { return HtmlTextWriterTag.Table; }
  441. }
  442. #endif
  443. private TableStyle TableStyle {
  444. // this will throw an InvalidCasException just like we need
  445. get { return (TableStyle) ControlStyle; }
  446. }
  447. private ArrayList ItemList {
  448. get {
  449. if (list == null)
  450. list = new ArrayList ();
  451. return list;
  452. }
  453. }
  454. void DoItem (int i, ListItemType t, object d, bool databind)
  455. {
  456. DataListItem itm = CreateItem (i, t);
  457. if (databind)
  458. itm.DataItem = d;
  459. DataListItemEventArgs e = new DataListItemEventArgs (itm);
  460. InitializeItem (itm);
  461. //
  462. // It is very important that this be called *before* data
  463. // binding. Otherwise, we won't save our state in the viewstate.
  464. //
  465. Controls.Add (itm);
  466. if (i != -1)
  467. ItemList.Add (itm);
  468. OnItemCreated (e);
  469. if (databind) {
  470. itm.DataBind ();
  471. OnItemDataBound (e);
  472. itm.DataItem = null;
  473. }
  474. }
  475. private void DoItemInLoop (int i, object d, bool databind, ListItemType type)
  476. {
  477. DoItem (i, type, d, databind);
  478. if (SeparatorTemplate != null)
  479. DoItem (i, ListItemType.Separator, null, databind);
  480. }
  481. protected override void CreateControlHierarchy (bool useDataSource)
  482. {
  483. Controls.Clear();
  484. IEnumerable ds = null;
  485. ArrayList keys = null;
  486. if (useDataSource) {
  487. idx = 0;
  488. ds = DataSourceResolver.ResolveDataSource (DataSource, DataMember);
  489. keys = DataKeysArray;
  490. keys.Clear ();
  491. } else {
  492. idx = (int) ViewState ["Items"];
  493. }
  494. if ((ds == null) && (idx == 0))
  495. return;
  496. if (headerTemplate != null)
  497. DoItem (-1, ListItemType.Header, null, useDataSource);
  498. // items
  499. int selected_index = SelectedIndex;
  500. int edit_item_index = EditItemIndex;
  501. ListItemType type;
  502. if (ds != null) {
  503. string key = DataKeyField;
  504. foreach (object o in ds) {
  505. if (useDataSource && key != "")
  506. keys.Add (DataBinder.GetPropertyValue (o, key));
  507. type = ListItemType.Item;
  508. if (idx == edit_item_index)
  509. type = ListItemType.EditItem;
  510. else if (idx == selected_index)
  511. type = ListItemType.SelectedItem;
  512. else if (idx % 2 != 0)
  513. type = ListItemType.AlternatingItem;
  514. DoItemInLoop (idx, o, useDataSource, type);
  515. idx++;
  516. }
  517. } else {
  518. for (int i = 0; i < idx; i++) {
  519. type = ListItemType.Item;
  520. if (idx == edit_item_index)
  521. type = ListItemType.EditItem;
  522. else if (idx == selected_index)
  523. type = ListItemType.SelectedItem;
  524. else if (idx % 2 != 0)
  525. type = ListItemType.AlternatingItem;
  526. DoItemInLoop (i, null, useDataSource, type);
  527. }
  528. }
  529. if (footerTemplate != null)
  530. DoItem (-1, ListItemType.Footer, null, useDataSource);
  531. ViewState ["Items"] = idx;
  532. }
  533. protected override Style CreateControlStyle ()
  534. {
  535. #if NET_2_0
  536. // not kept (directly) in the DataList ViewState
  537. return new TableStyle ();
  538. #else
  539. TableStyle tableStyle = new TableStyle (ViewState);
  540. tableStyle.CellSpacing = 0;
  541. return tableStyle;
  542. #endif
  543. }
  544. protected virtual DataListItem CreateItem (int itemIndex, ListItemType itemType)
  545. {
  546. return new DataListItem (itemIndex, itemType);
  547. }
  548. protected virtual void InitializeItem (DataListItem item)
  549. {
  550. ITemplate t = null;
  551. switch (item.ItemType) {
  552. case ListItemType.Header:
  553. t = HeaderTemplate;
  554. break;
  555. case ListItemType.Footer:
  556. t = FooterTemplate;
  557. break;
  558. case ListItemType.Separator:
  559. t = SeparatorTemplate;
  560. break;
  561. case ListItemType.Item:
  562. case ListItemType.AlternatingItem:
  563. case ListItemType.SelectedItem:
  564. case ListItemType.EditItem:
  565. int index = item.ItemIndex;
  566. if ((SelectedIndex == index) && (SelectedItemTemplate != null))
  567. t = SelectedItemTemplate;
  568. else if ((EditItemIndex == index) && (EditItemTemplate != null))
  569. t = EditItemTemplate;
  570. else if (((index & 1) == 0) || (alternatingItemTemplate == null))
  571. t = ItemTemplate;
  572. else
  573. t = alternatingItemTemplate;
  574. break;
  575. }
  576. if (t != null)
  577. t.InstantiateIn (item);
  578. }
  579. protected override void LoadViewState (object savedState)
  580. {
  581. object[] state = (object[]) savedState;
  582. base.LoadViewState (state [0]);
  583. if (state [1] != null)
  584. ItemStyle.LoadViewState (state [1]);
  585. if (state [2] != null)
  586. SelectedItemStyle.LoadViewState (state [2]);
  587. if (state [3] != null)
  588. AlternatingItemStyle.LoadViewState (state [3]);
  589. if (state [4] != null)
  590. EditItemStyle.LoadViewState (state [4]);
  591. if (state [5] != null)
  592. SeparatorStyle.LoadViewState (state [5]);
  593. if (state [6] != null)
  594. HeaderStyle.LoadViewState (state [6]);
  595. if (state [7] != null)
  596. FooterStyle.LoadViewState (state [7]);
  597. }
  598. protected override bool OnBubbleEvent (object source, EventArgs e)
  599. {
  600. DataListCommandEventArgs dlca = (e as DataListCommandEventArgs);
  601. if (dlca == null)
  602. return false;
  603. string cn = dlca.CommandName;
  604. CultureInfo inv = CultureInfo.InvariantCulture;
  605. OnItemCommand (dlca);
  606. if (String.Compare (cn, CancelCommandName, true, inv) == 0) {
  607. OnCancelCommand (dlca);
  608. return true;
  609. } else if (String.Compare (cn, DeleteCommandName, true, inv) == 0) {
  610. OnDeleteCommand (dlca);
  611. return true;
  612. } else if (String.Compare (cn, EditCommandName, true, inv) == 0) {
  613. OnEditCommand (dlca);
  614. return true;
  615. } else if (String.Compare (cn, SelectCommandName, true, inv) == 0) {
  616. OnSelectedIndexChanged (dlca);
  617. return true;
  618. } else if (String.Compare (cn, UpdateCommandName, true, inv) == 0) {
  619. OnUpdateCommand (dlca);
  620. return true;
  621. }
  622. return false;
  623. }
  624. protected virtual void OnCancelCommand (DataListCommandEventArgs e)
  625. {
  626. DataListCommandEventHandler cancelCommand = (DataListCommandEventHandler) Events [cancelCommandEvent];
  627. if (cancelCommand != null)
  628. cancelCommand (this, e);
  629. }
  630. protected virtual void OnDeleteCommand (DataListCommandEventArgs e)
  631. {
  632. DataListCommandEventHandler deleteCommand = (DataListCommandEventHandler) Events [deleteCommandEvent];
  633. if (deleteCommand != null)
  634. deleteCommand (this, e);
  635. }
  636. protected virtual void OnEditCommand (DataListCommandEventArgs e)
  637. {
  638. DataListCommandEventHandler editCommand = (DataListCommandEventHandler) Events [editCommandEvent];
  639. if (editCommand != null)
  640. editCommand (this, e);
  641. }
  642. #if NET_2_0
  643. protected internal override void OnInit (EventArgs e)
  644. {
  645. // EditItemIndex and SelectedIndex now use the Control State (i.e not the View State)
  646. Page.RegisterRequiresControlState (this);
  647. base.OnInit (e);
  648. }
  649. #endif
  650. protected virtual void OnItemCommand (DataListCommandEventArgs e)
  651. {
  652. DataListCommandEventHandler itemCommand = (DataListCommandEventHandler) Events [itemCommandEvent];
  653. if (itemCommand != null)
  654. itemCommand (this, e);
  655. }
  656. protected virtual void OnItemCreated (DataListItemEventArgs e)
  657. {
  658. DataListItemEventHandler itemCreated = (DataListItemEventHandler) Events [itemCreatedEvent];
  659. if (itemCreated != null)
  660. itemCreated (this, e);
  661. }
  662. protected virtual void OnItemDataBound (DataListItemEventArgs e)
  663. {
  664. DataListItemEventHandler itemDataBound = (DataListItemEventHandler) Events [itemDataBoundEvent];
  665. if (itemDataBound != null)
  666. itemDataBound (this, e);
  667. }
  668. protected virtual void OnUpdateCommand (DataListCommandEventArgs e)
  669. {
  670. DataListCommandEventHandler updateCommand = (DataListCommandEventHandler) Events [updateCommandEvent];
  671. if (updateCommand != null)
  672. updateCommand (this, e);
  673. }
  674. void ApplyControlStyle (Control ctrl, Style style)
  675. {
  676. if (style == null || false == ctrl.HasControls ())
  677. return;
  678. foreach (Control c in ctrl.Controls) {
  679. if (c is Table) {
  680. Table tbl = (Table) c;
  681. foreach (TableRow row in tbl.Rows)
  682. row.MergeStyle (style);
  683. }
  684. }
  685. }
  686. protected override void PrepareControlHierarchy ()
  687. {
  688. if (!HasControls () || Controls.Count == 0)
  689. return; // No one called CreateControlHierarchy() with DataSource != null
  690. Style alt = null;
  691. foreach (DataListItem item in Controls) {
  692. switch (item.ItemType) {
  693. case ListItemType.Item:
  694. item.MergeStyle (itemStyle);
  695. ApplyControlStyle (item, itemStyle);
  696. break;
  697. case ListItemType.AlternatingItem:
  698. if (alt == null) {
  699. if (alternatingItemStyle != null) {
  700. alt = new TableItemStyle ();
  701. alt.CopyFrom (itemStyle);
  702. alt.CopyFrom (alternatingItemStyle);
  703. } else {
  704. alt = itemStyle;
  705. }
  706. }
  707. item.MergeStyle (alt);
  708. ApplyControlStyle (item, alt);
  709. break;
  710. case ListItemType.EditItem:
  711. if (editItemStyle != null) {
  712. item.MergeStyle (editItemStyle);
  713. ApplyControlStyle (item, editItemStyle);
  714. } else {
  715. item.MergeStyle (itemStyle);
  716. ApplyControlStyle (item, itemStyle);
  717. }
  718. break;
  719. case ListItemType.Footer:
  720. if (!ShowFooter) {
  721. item.Visible = false;
  722. break;
  723. }
  724. if (footerStyle != null) {
  725. item.MergeStyle (footerStyle);
  726. ApplyControlStyle (item, footerStyle);
  727. }
  728. break;
  729. case ListItemType.Header:
  730. if (!ShowHeader) {
  731. item.Visible = false;
  732. break;
  733. }
  734. if (headerStyle != null) {
  735. item.MergeStyle (headerStyle);
  736. ApplyControlStyle (item, headerStyle);
  737. }
  738. break;
  739. case ListItemType.SelectedItem:
  740. if (selectedItemStyle != null) {
  741. item.MergeStyle (selectedItemStyle);
  742. ApplyControlStyle (item, selectedItemStyle);
  743. } else {
  744. item.MergeStyle (itemStyle);
  745. ApplyControlStyle (item, itemStyle);
  746. }
  747. break;
  748. case ListItemType.Separator:
  749. if (separatorStyle != null) {
  750. item.MergeStyle(separatorStyle);
  751. ApplyControlStyle (item, separatorStyle);
  752. }
  753. else {
  754. item.MergeStyle (itemStyle);
  755. ApplyControlStyle (item, itemStyle);
  756. }
  757. break;
  758. }
  759. }
  760. }
  761. #if NET_2_0
  762. protected internal
  763. #else
  764. protected
  765. #endif
  766. override void RenderContents (HtmlTextWriter writer)
  767. {
  768. if (Items.Count == 0)
  769. return;
  770. RepeatInfo ri = new RepeatInfo ();
  771. ri.RepeatColumns = RepeatColumns;
  772. ri.RepeatDirection = RepeatDirection;
  773. ri.RepeatLayout = RepeatLayout;
  774. ri.CaptionAlign = CaptionAlign;
  775. ri.Caption = Caption;
  776. ri.UseAccessibleHeader = UseAccessibleHeader;
  777. /*
  778. // debugging stuff that I prefer to keep for a while
  779. Console.WriteLine ("RepeatColumns {0}", ri.RepeatColumns);
  780. Console.WriteLine ("RepeatDirection {0}", ri.RepeatDirection);
  781. Console.WriteLine ("RepeatLayout {0}", ri.RepeatLayout);
  782. Console.WriteLine ("OuterTableImplied {0}", ExtractTemplateRows);
  783. Console.WriteLine ("IRepeatInfoUser.HasFooter {0}", (ShowFooter && (footerTemplate != null)));
  784. Console.WriteLine ("IRepeatInfoUser.HasHeader {0}", (ShowHeader && (headerTemplate != null)));
  785. Console.WriteLine ("IRepeatInfoUser.HasSeparators {0}", (separatorTemplate != null));
  786. Console.WriteLine ("IRepeatInfoUser.RepeatedItemCount {0}", Items.Count);
  787. for (int i=0; i < Items.Count; i++) {
  788. DataListItem dli = Items [i];
  789. Console.WriteLine ("{0}: Index {1}, Type {2}", i, dli.ItemIndex, dli.ItemType);
  790. }
  791. */
  792. bool extract = ExtractTemplateRows;
  793. if (extract) {
  794. ri.OuterTableImplied = true;
  795. writer.AddAttribute (HtmlTextWriterAttribute.Id, ClientID);
  796. if (ControlStyleCreated) {
  797. ControlStyle.AddAttributesToRender (writer);
  798. }
  799. writer.RenderBeginTag (HtmlTextWriterTag.Table);
  800. ri.RenderRepeater (writer, this, ControlStyle, this);
  801. writer.RenderEndTag ();
  802. } else {
  803. ri.RenderRepeater (writer, this, ControlStyle, this);
  804. }
  805. }
  806. protected override object SaveViewState ()
  807. {
  808. #if NET_2_0
  809. object[] state = new object [9];
  810. // FIXME: what's new in slot #0 ?
  811. state[8] = base.SaveViewState ();
  812. #else
  813. object[] state = new object [8];
  814. state[0] = base.SaveViewState ();
  815. #endif
  816. if (itemStyle != null)
  817. state [1] = itemStyle.SaveViewState ();
  818. if (selectedItemStyle != null)
  819. state [2] = selectedItemStyle.SaveViewState ();
  820. if (alternatingItemStyle != null)
  821. state [3] = alternatingItemStyle.SaveViewState ();
  822. if (editItemStyle != null)
  823. state [4] = editItemStyle.SaveViewState ();
  824. if (separatorStyle != null)
  825. state [5] = separatorStyle.SaveViewState ();
  826. if (headerStyle != null)
  827. state [6] = headerStyle.SaveViewState ();
  828. if (footerStyle != null)
  829. state [7] = footerStyle.SaveViewState ();
  830. return state;
  831. }
  832. protected override void TrackViewState ()
  833. {
  834. base.TrackViewState ();
  835. if (alternatingItemStyle != null)
  836. alternatingItemStyle.TrackViewState ();
  837. if (editItemStyle != null)
  838. editItemStyle.TrackViewState ();
  839. if (footerStyle != null)
  840. footerStyle.TrackViewState ();
  841. if (headerStyle != null)
  842. headerStyle.TrackViewState ();
  843. if (itemStyle != null)
  844. itemStyle.TrackViewState ();
  845. if (selectedItemStyle != null)
  846. selectedItemStyle.TrackViewState ();
  847. if (separatorStyle != null)
  848. separatorStyle.TrackViewState ();
  849. }
  850. [WebSysDescription ("")]
  851. [WebCategory ("Action")]
  852. public event DataListCommandEventHandler CancelCommand {
  853. add { Events.AddHandler (cancelCommandEvent, value); }
  854. remove { Events.RemoveHandler (cancelCommandEvent, value); }
  855. }
  856. [WebSysDescription ("")]
  857. [WebCategory ("Action")]
  858. public event DataListCommandEventHandler DeleteCommand {
  859. add { Events.AddHandler (deleteCommandEvent, value); }
  860. remove { Events.RemoveHandler (deleteCommandEvent, value); }
  861. }
  862. [WebSysDescription ("")]
  863. [WebCategory ("Action")]
  864. public event DataListCommandEventHandler EditCommand {
  865. add { Events.AddHandler (editCommandEvent, value); }
  866. remove { Events.RemoveHandler (editCommandEvent, value); }
  867. }
  868. [WebSysDescription ("")]
  869. [WebCategory ("Action")]
  870. public event DataListCommandEventHandler ItemCommand {
  871. add { Events.AddHandler (itemCommandEvent, value); }
  872. remove { Events.RemoveHandler (itemCommandEvent, value); }
  873. }
  874. [WebSysDescription ("")]
  875. [WebCategory ("Action")]
  876. public event DataListItemEventHandler ItemCreated {
  877. add { Events.AddHandler (itemCreatedEvent, value); }
  878. remove { Events.RemoveHandler (itemCreatedEvent, value); }
  879. }
  880. [WebSysDescription ("")]
  881. [WebCategory ("Action")]
  882. public event DataListItemEventHandler ItemDataBound {
  883. add { Events.AddHandler (itemDataBoundEvent, value); }
  884. remove { Events.RemoveHandler (itemDataBoundEvent, value); }
  885. }
  886. [WebSysDescription ("")]
  887. [WebCategory ("Action")]
  888. public event DataListCommandEventHandler UpdateCommand {
  889. add { Events.AddHandler (updateCommandEvent, value); }
  890. remove { Events.RemoveHandler (updateCommandEvent, value); }
  891. }
  892. // IRepeatInfoUser support
  893. bool IRepeatInfoUser.HasFooter {
  894. get { return (ShowFooter && (footerTemplate != null)); }
  895. }
  896. bool IRepeatInfoUser.HasHeader {
  897. get { return (ShowHeader && (headerTemplate != null)); }
  898. }
  899. bool IRepeatInfoUser.HasSeparators {
  900. get { return (separatorTemplate != null); }
  901. }
  902. // don't include header, footer and separators in the count
  903. int IRepeatInfoUser.RepeatedItemCount {
  904. get {
  905. if (idx == -1) {
  906. object o = ViewState ["Items"];
  907. idx = (o == null) ? 0 : (int) o;
  908. }
  909. return idx;
  910. }
  911. }
  912. Style IRepeatInfoUser.GetItemStyle (ListItemType itemType, int repeatIndex)
  913. {
  914. DataListItem item = null;
  915. switch (itemType) {
  916. case ListItemType.Header:
  917. case ListItemType.Footer:
  918. if (repeatIndex >= 0 && (!HasControls () || repeatIndex >= Controls.Count))
  919. throw new ArgumentOutOfRangeException ();
  920. item = FindFirstItem (itemType);
  921. break;
  922. case ListItemType.Item:
  923. case ListItemType.AlternatingItem:
  924. case ListItemType.SelectedItem:
  925. case ListItemType.EditItem:
  926. if (repeatIndex >= 0 && (!HasControls () || repeatIndex >= Controls.Count))
  927. throw new ArgumentOutOfRangeException ();
  928. item = FindBestItem (repeatIndex);
  929. break;
  930. case ListItemType.Separator:
  931. if (repeatIndex >= 0 && (!HasControls () || repeatIndex >= Controls.Count))
  932. throw new ArgumentOutOfRangeException ();
  933. item = FindSpecificItem (itemType, repeatIndex);
  934. break;
  935. default:
  936. item = null;
  937. break;
  938. }
  939. if (item == null || item.ControlStyleCreated == false)
  940. return null;
  941. return item.ControlStyle;
  942. }
  943. // Header and Footer don't have a "real" index (-1)
  944. private DataListItem FindFirstItem (ListItemType itemType)
  945. {
  946. for (int i = 0; i < Controls.Count; i++) {
  947. DataListItem item = (Controls [i] as DataListItem);
  948. if ((item != null) && (item.ItemType == itemType))
  949. return item;
  950. }
  951. return null;
  952. }
  953. // Both Type and Index must match (e.g. Separator)
  954. private DataListItem FindSpecificItem (ListItemType itemType, int repeatIndex)
  955. {
  956. for (int i = 0; i < Controls.Count; i++) {
  957. DataListItem item = (Controls [i] as DataListItem);
  958. if ((item != null) && (item.ItemType == itemType) && (item.ItemIndex == repeatIndex))
  959. return item;
  960. }
  961. return null;
  962. }
  963. // we get call for Item even for AlternatingItem :(
  964. private DataListItem FindBestItem (int repeatIndex)
  965. {
  966. for (int i = 0; i < Controls.Count; i++) {
  967. DataListItem item = (Controls [i] as DataListItem);
  968. if ((item != null) && (item.ItemIndex == repeatIndex)) {
  969. switch (item.ItemType) {
  970. case ListItemType.Item:
  971. case ListItemType.AlternatingItem:
  972. case ListItemType.SelectedItem:
  973. case ListItemType.EditItem:
  974. return item;
  975. default:
  976. return null;
  977. }
  978. }
  979. }
  980. return null;
  981. }
  982. void IRepeatInfoUser.RenderItem (ListItemType itemType, int repeatIndex, RepeatInfo repeatInfo, HtmlTextWriter writer)
  983. {
  984. // if possible take the easy way out...
  985. if (!HasControls ())
  986. return;
  987. DataListItem item = null;
  988. switch (itemType) {
  989. case ListItemType.Header:
  990. case ListItemType.Footer:
  991. item = FindFirstItem (itemType);
  992. break;
  993. case ListItemType.Item:
  994. case ListItemType.AlternatingItem:
  995. case ListItemType.SelectedItem:
  996. case ListItemType.EditItem:
  997. item = FindBestItem (repeatIndex);
  998. break;
  999. case ListItemType.Separator:
  1000. item = FindSpecificItem (itemType, repeatIndex);
  1001. break;
  1002. }
  1003. if (item != null) {
  1004. bool extract = ExtractTemplateRows;
  1005. bool table = (RepeatLayout == RepeatLayout.Table);
  1006. if (!table || extract) {
  1007. // sadly RepeatInfo doesn't support Style for RepeatLayout.Flow
  1008. Style s = (this as IRepeatInfoUser).GetItemStyle (itemType, repeatIndex);
  1009. if (s != null)
  1010. item.ControlStyle.CopyFrom (s);
  1011. }
  1012. //Console.WriteLine ("RenderItem #{0} type {1}", repeatIndex, itemType);
  1013. item.RenderItem (writer, extract, table);
  1014. } else {
  1015. //Console.WriteLine ("Couldn't find #{0} type {1} out of {2} items / {3} controls", repeatIndex, itemType, Items.Count, Controls.Count);
  1016. }
  1017. }
  1018. }
  1019. }