DataList.cs 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148
  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. #if NET_2_0
  489. if (IsBoundUsingDataSourceID)
  490. ds = GetData();
  491. else
  492. #endif
  493. ds = DataSourceResolver.ResolveDataSource (DataSource, DataMember);
  494. keys = DataKeysArray;
  495. keys.Clear ();
  496. } else {
  497. idx = (int) ViewState ["Items"];
  498. }
  499. if ((ds == null) && (idx == 0))
  500. return;
  501. if (headerTemplate != null)
  502. DoItem (-1, ListItemType.Header, null, useDataSource);
  503. // items
  504. int selected_index = SelectedIndex;
  505. int edit_item_index = EditItemIndex;
  506. ListItemType type;
  507. if (ds != null) {
  508. string key = DataKeyField;
  509. foreach (object o in ds) {
  510. if (useDataSource && key != "")
  511. keys.Add (DataBinder.GetPropertyValue (o, key));
  512. type = ListItemType.Item;
  513. if (idx == edit_item_index)
  514. type = ListItemType.EditItem;
  515. else if (idx == selected_index)
  516. type = ListItemType.SelectedItem;
  517. else if (idx % 2 != 0)
  518. type = ListItemType.AlternatingItem;
  519. DoItemInLoop (idx, o, useDataSource, type);
  520. idx++;
  521. }
  522. } else {
  523. for (int i = 0; i < idx; i++) {
  524. type = ListItemType.Item;
  525. if (idx == edit_item_index)
  526. type = ListItemType.EditItem;
  527. else if (idx == selected_index)
  528. type = ListItemType.SelectedItem;
  529. else if (idx % 2 != 0)
  530. type = ListItemType.AlternatingItem;
  531. DoItemInLoop (i, null, useDataSource, type);
  532. }
  533. }
  534. if (footerTemplate != null)
  535. DoItem (-1, ListItemType.Footer, null, useDataSource);
  536. ViewState ["Items"] = idx;
  537. }
  538. protected override Style CreateControlStyle ()
  539. {
  540. #if NET_2_0
  541. // not kept (directly) in the DataList ViewState
  542. return new TableStyle ();
  543. #else
  544. TableStyle tableStyle = new TableStyle (ViewState);
  545. tableStyle.CellSpacing = 0;
  546. return tableStyle;
  547. #endif
  548. }
  549. protected virtual DataListItem CreateItem (int itemIndex, ListItemType itemType)
  550. {
  551. return new DataListItem (itemIndex, itemType);
  552. }
  553. protected virtual void InitializeItem (DataListItem item)
  554. {
  555. ITemplate t = null;
  556. switch (item.ItemType) {
  557. case ListItemType.Header:
  558. t = HeaderTemplate;
  559. break;
  560. case ListItemType.Footer:
  561. t = FooterTemplate;
  562. break;
  563. case ListItemType.Separator:
  564. t = SeparatorTemplate;
  565. break;
  566. case ListItemType.Item:
  567. case ListItemType.AlternatingItem:
  568. case ListItemType.SelectedItem:
  569. case ListItemType.EditItem:
  570. int index = item.ItemIndex;
  571. if ((EditItemIndex == index) && (EditItemTemplate != null))
  572. t = EditItemTemplate;
  573. else if ((SelectedIndex == index) && (SelectedItemTemplate != null))
  574. t = SelectedItemTemplate;
  575. else if (((index & 1) == 0) || (alternatingItemTemplate == null))
  576. t = ItemTemplate;
  577. else
  578. t = alternatingItemTemplate;
  579. break;
  580. }
  581. if (t != null)
  582. t.InstantiateIn (item);
  583. }
  584. protected override void LoadViewState (object savedState)
  585. {
  586. object[] state = (object[]) savedState;
  587. #if NET_2_0
  588. base.LoadViewState (state [8]);
  589. #else
  590. base.LoadViewState (state [0]);
  591. #endif
  592. if (state [1] != null)
  593. ItemStyle.LoadViewState (state [1]);
  594. if (state [2] != null)
  595. SelectedItemStyle.LoadViewState (state [2]);
  596. if (state [3] != null)
  597. AlternatingItemStyle.LoadViewState (state [3]);
  598. if (state [4] != null)
  599. EditItemStyle.LoadViewState (state [4]);
  600. if (state [5] != null)
  601. SeparatorStyle.LoadViewState (state [5]);
  602. if (state [6] != null)
  603. HeaderStyle.LoadViewState (state [6]);
  604. if (state [7] != null)
  605. FooterStyle.LoadViewState (state [7]);
  606. }
  607. protected override bool OnBubbleEvent (object source, EventArgs e)
  608. {
  609. DataListCommandEventArgs dlca = (e as DataListCommandEventArgs);
  610. if (dlca == null)
  611. return false;
  612. string cn = dlca.CommandName;
  613. CultureInfo inv = CultureInfo.InvariantCulture;
  614. OnItemCommand (dlca);
  615. if (String.Compare (cn, CancelCommandName, true, inv) == 0) {
  616. OnCancelCommand (dlca);
  617. return true;
  618. } else if (String.Compare (cn, DeleteCommandName, true, inv) == 0) {
  619. OnDeleteCommand (dlca);
  620. return true;
  621. } else if (String.Compare (cn, EditCommandName, true, inv) == 0) {
  622. OnEditCommand (dlca);
  623. return true;
  624. } else if (String.Compare (cn, SelectCommandName, true, inv) == 0) {
  625. OnSelectedIndexChanged (dlca);
  626. return true;
  627. } else if (String.Compare (cn, UpdateCommandName, true, inv) == 0) {
  628. OnUpdateCommand (dlca);
  629. return true;
  630. }
  631. return false;
  632. }
  633. protected virtual void OnCancelCommand (DataListCommandEventArgs e)
  634. {
  635. DataListCommandEventHandler cancelCommand = (DataListCommandEventHandler) Events [cancelCommandEvent];
  636. if (cancelCommand != null)
  637. cancelCommand (this, e);
  638. }
  639. protected virtual void OnDeleteCommand (DataListCommandEventArgs e)
  640. {
  641. DataListCommandEventHandler deleteCommand = (DataListCommandEventHandler) Events [deleteCommandEvent];
  642. if (deleteCommand != null)
  643. deleteCommand (this, e);
  644. }
  645. protected virtual void OnEditCommand (DataListCommandEventArgs e)
  646. {
  647. DataListCommandEventHandler editCommand = (DataListCommandEventHandler) Events [editCommandEvent];
  648. if (editCommand != null)
  649. editCommand (this, e);
  650. }
  651. #if NET_2_0
  652. protected internal override void OnInit (EventArgs e)
  653. {
  654. // EditItemIndex and SelectedIndex now use the Control State (i.e not the View State)
  655. Page.RegisterRequiresControlState (this);
  656. base.OnInit (e);
  657. }
  658. #endif
  659. protected virtual void OnItemCommand (DataListCommandEventArgs e)
  660. {
  661. DataListCommandEventHandler itemCommand = (DataListCommandEventHandler) Events [itemCommandEvent];
  662. if (itemCommand != null)
  663. itemCommand (this, e);
  664. }
  665. protected virtual void OnItemCreated (DataListItemEventArgs e)
  666. {
  667. DataListItemEventHandler itemCreated = (DataListItemEventHandler) Events [itemCreatedEvent];
  668. if (itemCreated != null)
  669. itemCreated (this, e);
  670. }
  671. protected virtual void OnItemDataBound (DataListItemEventArgs e)
  672. {
  673. DataListItemEventHandler itemDataBound = (DataListItemEventHandler) Events [itemDataBoundEvent];
  674. if (itemDataBound != null)
  675. itemDataBound (this, e);
  676. }
  677. protected virtual void OnUpdateCommand (DataListCommandEventArgs e)
  678. {
  679. DataListCommandEventHandler updateCommand = (DataListCommandEventHandler) Events [updateCommandEvent];
  680. if (updateCommand != null)
  681. updateCommand (this, e);
  682. }
  683. void ApplyControlStyle (Control ctrl, Style style, bool apply_to_rows)
  684. {
  685. if (style == null || false == ctrl.HasControls ())
  686. return;
  687. foreach (Control c in ctrl.Controls) {
  688. if (c is Table) {
  689. Table tbl = (Table) c;
  690. if (apply_to_rows) {
  691. foreach (TableRow row in tbl.Rows)
  692. row.MergeStyle (style);
  693. } else {
  694. tbl.MergeStyle (style);
  695. }
  696. }
  697. }
  698. }
  699. protected override void PrepareControlHierarchy ()
  700. {
  701. if (!HasControls () || Controls.Count == 0)
  702. return; // No one called CreateControlHierarchy() with DataSource != null
  703. Style alt = null;
  704. bool apply_to_rows = ExtractTemplateRows;
  705. foreach (DataListItem item in Controls) {
  706. switch (item.ItemType) {
  707. case ListItemType.Item:
  708. item.MergeStyle (itemStyle);
  709. ApplyControlStyle (item, itemStyle, apply_to_rows);
  710. break;
  711. case ListItemType.AlternatingItem:
  712. if (alt == null) {
  713. if (alternatingItemStyle != null) {
  714. alt = new TableItemStyle ();
  715. alt.CopyFrom (itemStyle);
  716. alt.CopyFrom (alternatingItemStyle);
  717. } else {
  718. alt = itemStyle;
  719. }
  720. }
  721. if (itemStyle != null)
  722. Console.WriteLine ("itemStyle.BackColor: {0}", itemStyle.BackColor);
  723. if (alternatingItemStyle != null)
  724. Console.WriteLine ("alternatingItemStyle.BackColor: {0}", alternatingItemStyle.BackColor);
  725. Console.WriteLine ("alt.BackColor: {0}", alt.BackColor);
  726. item.MergeStyle (alt);
  727. ApplyControlStyle (item, alt, apply_to_rows);
  728. break;
  729. case ListItemType.EditItem:
  730. if (editItemStyle != null) {
  731. item.MergeStyle (editItemStyle);
  732. ApplyControlStyle (item, editItemStyle, apply_to_rows);
  733. } else {
  734. item.MergeStyle (itemStyle);
  735. ApplyControlStyle (item, itemStyle, apply_to_rows);
  736. }
  737. break;
  738. case ListItemType.Footer:
  739. if (!ShowFooter) {
  740. item.Visible = false;
  741. break;
  742. }
  743. if (footerStyle != null) {
  744. item.MergeStyle (footerStyle);
  745. ApplyControlStyle (item, footerStyle, apply_to_rows);
  746. }
  747. break;
  748. case ListItemType.Header:
  749. if (!ShowHeader) {
  750. item.Visible = false;
  751. break;
  752. }
  753. if (headerStyle != null) {
  754. item.MergeStyle (headerStyle);
  755. ApplyControlStyle (item, headerStyle, apply_to_rows);
  756. }
  757. break;
  758. case ListItemType.SelectedItem:
  759. if (selectedItemStyle != null) {
  760. item.MergeStyle (selectedItemStyle);
  761. ApplyControlStyle (item, selectedItemStyle, apply_to_rows);
  762. } else {
  763. item.MergeStyle (itemStyle);
  764. ApplyControlStyle (item, itemStyle, apply_to_rows);
  765. }
  766. break;
  767. case ListItemType.Separator:
  768. if (separatorStyle != null) {
  769. item.MergeStyle(separatorStyle);
  770. ApplyControlStyle (item, separatorStyle, apply_to_rows);
  771. }
  772. else {
  773. item.MergeStyle (itemStyle);
  774. ApplyControlStyle (item, itemStyle, apply_to_rows);
  775. }
  776. break;
  777. }
  778. }
  779. }
  780. #if NET_2_0
  781. protected internal
  782. #else
  783. protected
  784. #endif
  785. override void RenderContents (HtmlTextWriter writer)
  786. {
  787. if (Items.Count == 0)
  788. return;
  789. RepeatInfo ri = new RepeatInfo ();
  790. ri.RepeatColumns = RepeatColumns;
  791. ri.RepeatDirection = RepeatDirection;
  792. ri.RepeatLayout = RepeatLayout;
  793. ri.CaptionAlign = CaptionAlign;
  794. ri.Caption = Caption;
  795. ri.UseAccessibleHeader = UseAccessibleHeader;
  796. /*
  797. // debugging stuff that I prefer to keep for a while
  798. Console.WriteLine ("RepeatColumns {0}", ri.RepeatColumns);
  799. Console.WriteLine ("RepeatDirection {0}", ri.RepeatDirection);
  800. Console.WriteLine ("RepeatLayout {0}", ri.RepeatLayout);
  801. Console.WriteLine ("OuterTableImplied {0}", ExtractTemplateRows);
  802. Console.WriteLine ("IRepeatInfoUser.HasFooter {0}", (ShowFooter && (footerTemplate != null)));
  803. Console.WriteLine ("IRepeatInfoUser.HasHeader {0}", (ShowHeader && (headerTemplate != null)));
  804. Console.WriteLine ("IRepeatInfoUser.HasSeparators {0}", (separatorTemplate != null));
  805. Console.WriteLine ("IRepeatInfoUser.RepeatedItemCount {0}", Items.Count);
  806. for (int i=0; i < Items.Count; i++) {
  807. DataListItem dli = Items [i];
  808. Console.WriteLine ("{0}: Index {1}, Type {2}", i, dli.ItemIndex, dli.ItemType);
  809. }
  810. */
  811. bool extract = ExtractTemplateRows;
  812. if (extract) {
  813. ri.OuterTableImplied = true;
  814. writer.AddAttribute (HtmlTextWriterAttribute.Id, ClientID);
  815. if (ControlStyleCreated) {
  816. ControlStyle.AddAttributesToRender (writer);
  817. }
  818. writer.RenderBeginTag (HtmlTextWriterTag.Table);
  819. ri.RenderRepeater (writer, this, ControlStyle, this);
  820. writer.RenderEndTag ();
  821. } else {
  822. ri.RenderRepeater (writer, this, ControlStyle, this);
  823. }
  824. }
  825. protected override object SaveViewState ()
  826. {
  827. #if NET_2_0
  828. object[] state = new object [9];
  829. // FIXME: what's new in slot #0 ?
  830. state[8] = base.SaveViewState ();
  831. #else
  832. object[] state = new object [8];
  833. state[0] = base.SaveViewState ();
  834. #endif
  835. if (itemStyle != null)
  836. state [1] = itemStyle.SaveViewState ();
  837. if (selectedItemStyle != null)
  838. state [2] = selectedItemStyle.SaveViewState ();
  839. if (alternatingItemStyle != null)
  840. state [3] = alternatingItemStyle.SaveViewState ();
  841. if (editItemStyle != null)
  842. state [4] = editItemStyle.SaveViewState ();
  843. if (separatorStyle != null)
  844. state [5] = separatorStyle.SaveViewState ();
  845. if (headerStyle != null)
  846. state [6] = headerStyle.SaveViewState ();
  847. if (footerStyle != null)
  848. state [7] = footerStyle.SaveViewState ();
  849. return state;
  850. }
  851. protected override void TrackViewState ()
  852. {
  853. base.TrackViewState ();
  854. if (alternatingItemStyle != null)
  855. alternatingItemStyle.TrackViewState ();
  856. if (editItemStyle != null)
  857. editItemStyle.TrackViewState ();
  858. if (footerStyle != null)
  859. footerStyle.TrackViewState ();
  860. if (headerStyle != null)
  861. headerStyle.TrackViewState ();
  862. if (itemStyle != null)
  863. itemStyle.TrackViewState ();
  864. if (selectedItemStyle != null)
  865. selectedItemStyle.TrackViewState ();
  866. if (separatorStyle != null)
  867. separatorStyle.TrackViewState ();
  868. }
  869. [WebSysDescription ("")]
  870. [WebCategory ("Action")]
  871. public event DataListCommandEventHandler CancelCommand {
  872. add { Events.AddHandler (cancelCommandEvent, value); }
  873. remove { Events.RemoveHandler (cancelCommandEvent, value); }
  874. }
  875. [WebSysDescription ("")]
  876. [WebCategory ("Action")]
  877. public event DataListCommandEventHandler DeleteCommand {
  878. add { Events.AddHandler (deleteCommandEvent, value); }
  879. remove { Events.RemoveHandler (deleteCommandEvent, value); }
  880. }
  881. [WebSysDescription ("")]
  882. [WebCategory ("Action")]
  883. public event DataListCommandEventHandler EditCommand {
  884. add { Events.AddHandler (editCommandEvent, value); }
  885. remove { Events.RemoveHandler (editCommandEvent, value); }
  886. }
  887. [WebSysDescription ("")]
  888. [WebCategory ("Action")]
  889. public event DataListCommandEventHandler ItemCommand {
  890. add { Events.AddHandler (itemCommandEvent, value); }
  891. remove { Events.RemoveHandler (itemCommandEvent, value); }
  892. }
  893. [WebSysDescription ("")]
  894. [WebCategory ("Action")]
  895. public event DataListItemEventHandler ItemCreated {
  896. add { Events.AddHandler (itemCreatedEvent, value); }
  897. remove { Events.RemoveHandler (itemCreatedEvent, value); }
  898. }
  899. [WebSysDescription ("")]
  900. [WebCategory ("Action")]
  901. public event DataListItemEventHandler ItemDataBound {
  902. add { Events.AddHandler (itemDataBoundEvent, value); }
  903. remove { Events.RemoveHandler (itemDataBoundEvent, value); }
  904. }
  905. [WebSysDescription ("")]
  906. [WebCategory ("Action")]
  907. public event DataListCommandEventHandler UpdateCommand {
  908. add { Events.AddHandler (updateCommandEvent, value); }
  909. remove { Events.RemoveHandler (updateCommandEvent, value); }
  910. }
  911. // IRepeatInfoUser support
  912. bool IRepeatInfoUser.HasFooter {
  913. get { return (ShowFooter && (footerTemplate != null)); }
  914. }
  915. bool IRepeatInfoUser.HasHeader {
  916. get { return (ShowHeader && (headerTemplate != null)); }
  917. }
  918. bool IRepeatInfoUser.HasSeparators {
  919. get { return (separatorTemplate != null); }
  920. }
  921. // don't include header, footer and separators in the count
  922. int IRepeatInfoUser.RepeatedItemCount {
  923. get {
  924. if (idx == -1) {
  925. object o = ViewState ["Items"];
  926. idx = (o == null) ? 0 : (int) o;
  927. }
  928. return idx;
  929. }
  930. }
  931. Style IRepeatInfoUser.GetItemStyle (ListItemType itemType, int repeatIndex)
  932. {
  933. DataListItem item = null;
  934. switch (itemType) {
  935. case ListItemType.Header:
  936. case ListItemType.Footer:
  937. if (repeatIndex >= 0 && (!HasControls () || repeatIndex >= Controls.Count))
  938. throw new ArgumentOutOfRangeException ();
  939. item = FindFirstItem (itemType);
  940. break;
  941. case ListItemType.Item:
  942. case ListItemType.AlternatingItem:
  943. case ListItemType.SelectedItem:
  944. case ListItemType.EditItem:
  945. if (repeatIndex >= 0 && (!HasControls () || repeatIndex >= Controls.Count))
  946. throw new ArgumentOutOfRangeException ();
  947. item = FindBestItem (repeatIndex);
  948. break;
  949. case ListItemType.Separator:
  950. if (repeatIndex >= 0 && (!HasControls () || repeatIndex >= Controls.Count))
  951. throw new ArgumentOutOfRangeException ();
  952. item = FindSpecificItem (itemType, repeatIndex);
  953. break;
  954. default:
  955. item = null;
  956. break;
  957. }
  958. if (item == null || item.ControlStyleCreated == false)
  959. return null;
  960. return item.ControlStyle;
  961. }
  962. // Header and Footer don't have a "real" index (-1)
  963. private DataListItem FindFirstItem (ListItemType itemType)
  964. {
  965. for (int i = 0; i < Controls.Count; i++) {
  966. DataListItem item = (Controls [i] as DataListItem);
  967. if ((item != null) && (item.ItemType == itemType))
  968. return item;
  969. }
  970. return null;
  971. }
  972. // Both Type and Index must match (e.g. Separator)
  973. private DataListItem FindSpecificItem (ListItemType itemType, int repeatIndex)
  974. {
  975. for (int i = 0; i < Controls.Count; i++) {
  976. DataListItem item = (Controls [i] as DataListItem);
  977. if ((item != null) && (item.ItemType == itemType) && (item.ItemIndex == repeatIndex))
  978. return item;
  979. }
  980. return null;
  981. }
  982. // we get call for Item even for AlternatingItem :(
  983. private DataListItem FindBestItem (int repeatIndex)
  984. {
  985. for (int i = 0; i < Controls.Count; i++) {
  986. DataListItem item = (Controls [i] as DataListItem);
  987. if ((item != null) && (item.ItemIndex == repeatIndex)) {
  988. switch (item.ItemType) {
  989. case ListItemType.Item:
  990. case ListItemType.AlternatingItem:
  991. case ListItemType.SelectedItem:
  992. case ListItemType.EditItem:
  993. return item;
  994. default:
  995. return null;
  996. }
  997. }
  998. }
  999. return null;
  1000. }
  1001. void IRepeatInfoUser.RenderItem (ListItemType itemType, int repeatIndex, RepeatInfo repeatInfo, HtmlTextWriter writer)
  1002. {
  1003. // if possible take the easy way out...
  1004. if (!HasControls ())
  1005. return;
  1006. DataListItem item = null;
  1007. switch (itemType) {
  1008. case ListItemType.Header:
  1009. case ListItemType.Footer:
  1010. item = FindFirstItem (itemType);
  1011. break;
  1012. case ListItemType.Item:
  1013. case ListItemType.AlternatingItem:
  1014. case ListItemType.SelectedItem:
  1015. case ListItemType.EditItem:
  1016. item = FindBestItem (repeatIndex);
  1017. break;
  1018. case ListItemType.Separator:
  1019. item = FindSpecificItem (itemType, repeatIndex);
  1020. break;
  1021. }
  1022. if (item != null) {
  1023. bool extract = ExtractTemplateRows;
  1024. bool table = (RepeatLayout == RepeatLayout.Table);
  1025. if (!table || extract) {
  1026. // sadly RepeatInfo doesn't support Style for RepeatLayout.Flow
  1027. Style s = (this as IRepeatInfoUser).GetItemStyle (itemType, repeatIndex);
  1028. if (s != null)
  1029. item.ControlStyle.CopyFrom (s);
  1030. }
  1031. //Console.WriteLine ("RenderItem #{0} type {1}", repeatIndex, itemType);
  1032. item.RenderItem (writer, extract, table);
  1033. } else {
  1034. //Console.WriteLine ("Couldn't find #{0} type {1} out of {2} items / {3} controls", repeatIndex, itemType, Items.Count, Controls.Count);
  1035. }
  1036. }
  1037. }
  1038. }