DataList.cs 32 KB

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