DataList.cs 28 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004
  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 { ViewState ["RepeatColumns"] = value; }
  287. }
  288. #if ONLY_1_1
  289. [Bindable (true)]
  290. #endif
  291. [DefaultValue (RepeatDirection.Vertical)]
  292. [WebSysDescription ("")]
  293. [WebCategory ("Layout")]
  294. public virtual RepeatDirection RepeatDirection {
  295. get {
  296. object o = ViewState ["RepeatDirection"];
  297. return (o == null) ? RepeatDirection.Vertical : (RepeatDirection) o;
  298. }
  299. set { ViewState ["RepeatDirection"] = value; }
  300. }
  301. #if ONLY_1_1
  302. [Bindable (true)]
  303. #endif
  304. [DefaultValue (RepeatLayout.Table)]
  305. [WebSysDescription ("")]
  306. [WebCategory ("Layout")]
  307. public virtual RepeatLayout RepeatLayout {
  308. get {
  309. object o = ViewState ["RepeatLayout"];
  310. return (o == null) ? RepeatLayout.Table : (RepeatLayout) o;
  311. }
  312. set { ViewState ["RepeatLayout"] = value; }
  313. }
  314. [Bindable (true)]
  315. [DefaultValue (-1)]
  316. [WebSysDescription ("")]
  317. [WebCategory ("Layout")]
  318. public virtual int SelectedIndex {
  319. get {
  320. object o = ViewState ["SelectedIndex"];
  321. return (o == null) ? -1 : (int) o;
  322. }
  323. set {
  324. if (value < -1)
  325. throw new ArgumentOutOfRangeException ("SelectedIndex", "< -1");
  326. ViewState ["SelectedIndex"] = value;
  327. }
  328. }
  329. [Browsable (false)]
  330. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  331. [WebSysDescription ("")]
  332. [WebCategory ("Layout")]
  333. public virtual DataListItem SelectedItem {
  334. get {
  335. if (SelectedIndex < 0)
  336. return null;
  337. if (SelectedIndex >= Items.Count)
  338. throw new ArgumentOutOfRangeException ("SelectedItem", ">= Items.Count");
  339. return items [SelectedIndex];
  340. }
  341. }
  342. [DefaultValue (null)]
  343. [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
  344. [NotifyParentProperty (true)]
  345. [PersistenceMode (PersistenceMode.InnerProperty)]
  346. [WebSysDescription ("")]
  347. [WebCategory ("Style")]
  348. public virtual TableItemStyle SelectedItemStyle {
  349. get {
  350. if (selectedItemStyle == null) {
  351. selectedItemStyle = new TableItemStyle ();
  352. if (IsTrackingViewState) {
  353. selectedItemStyle.TrackViewState ();
  354. }
  355. }
  356. return selectedItemStyle;
  357. }
  358. }
  359. [Browsable (false)]
  360. [DefaultValue (null)]
  361. [TemplateContainer (typeof (DataListItem))]
  362. [PersistenceMode (PersistenceMode.InnerProperty)]
  363. [WebSysDescription ("")]
  364. [WebCategory ("Style")]
  365. public virtual ITemplate SelectedItemTemplate {
  366. get { return selectedItemTemplate; }
  367. set { selectedItemTemplate = value; }
  368. }
  369. [DefaultValue (null)]
  370. [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
  371. [NotifyParentProperty (true)]
  372. [PersistenceMode (PersistenceMode.InnerProperty)]
  373. [WebSysDescription ("")]
  374. [WebCategory ("Style")]
  375. public virtual TableItemStyle SeparatorStyle {
  376. get {
  377. if (separatorStyle == null) {
  378. separatorStyle = new TableItemStyle ();
  379. if (IsTrackingViewState) {
  380. separatorStyle.TrackViewState ();
  381. }
  382. }
  383. return separatorStyle;
  384. }
  385. }
  386. [Browsable (false)]
  387. [DefaultValue (null)]
  388. [TemplateContainer (typeof (DataListItem))]
  389. [PersistenceMode (PersistenceMode.InnerProperty)]
  390. [WebSysDescription ("")]
  391. [WebCategory ("Style")]
  392. public virtual ITemplate SeparatorTemplate {
  393. get { return separatorTemplate; }
  394. set { separatorTemplate = value; }
  395. }
  396. #if ONLY_1_1
  397. [Bindable (true)]
  398. #endif
  399. [DefaultValue (true)]
  400. [WebSysDescription ("")]
  401. [WebCategory ("Appearance")]
  402. public virtual bool ShowFooter {
  403. get {
  404. object o = ViewState ["ShowFooter"];
  405. return (o == null) ? true : (bool) o;
  406. }
  407. set { ViewState ["ShowFooter"] = value; }
  408. }
  409. #if ONLY_1_1
  410. [Bindable (true)]
  411. #endif
  412. [DefaultValue (true)]
  413. [WebSysDescription ("")]
  414. [WebCategory ("Appearance")]
  415. public virtual bool ShowHeader {
  416. get {
  417. object o = ViewState ["ShowHeader"];
  418. return (o == null) ? true : (bool) o;
  419. }
  420. set { ViewState ["ShowHeader"] = value; }
  421. }
  422. #if NET_2_0
  423. [MonoTODO ("incomplete")]
  424. [Browsable (false)]
  425. public object SelectedValue {
  426. get {
  427. if (DataKeyField.Length == 0)
  428. throw new InvalidOperationException (Locale.GetText ("No DataKeyField present."));
  429. if ((SelectedIndex >= 0) && (selectedIndex < DataKeys.Count)) {
  430. return DataKeys [selectedIndex];
  431. }
  432. return null;
  433. }
  434. }
  435. protected override HtmlTextWriterTag TagKey {
  436. get { return HtmlTextWriterTag.Table; }
  437. }
  438. #endif
  439. private TableStyle TableStyle {
  440. // this will throw an InvalidCasException just like we need
  441. get { return (TableStyle) ControlStyle; }
  442. }
  443. private ArrayList ItemList {
  444. get {
  445. if (list == null)
  446. list = new ArrayList ();
  447. return list;
  448. }
  449. }
  450. void DoItem (int i, ListItemType t, object d, bool databind)
  451. {
  452. DataListItem itm = CreateItem (i, t);
  453. itm.DataItem = d;
  454. DataListItemEventArgs e = new DataListItemEventArgs (itm);
  455. InitializeItem (itm);
  456. //
  457. // It is very important that this be called *before* data
  458. // binding. Otherwise, we won't save our state in the viewstate.
  459. //
  460. Controls.Add (itm);
  461. if (i != -1)
  462. ItemList.Add (itm);
  463. OnItemCreated (e);
  464. if (databind) {
  465. itm.DataBind ();
  466. OnItemDataBound (e);
  467. }
  468. }
  469. private void DoItemInLoop (int i, object d, bool databind)
  470. {
  471. if (i > 0 && SeparatorTemplate != null)
  472. DoItem (i - 1, ListItemType.Separator, null, databind);
  473. DoItem (i, i % 2 == 0 ? ListItemType.Item : ListItemType.AlternatingItem, d, databind);
  474. }
  475. protected override void CreateControlHierarchy (bool useDataSource)
  476. {
  477. Controls.Clear();
  478. IEnumerable ds = null;
  479. if (useDataSource) {
  480. idx = 0;
  481. ds = DataSourceResolver.ResolveDataSource (DataSource, DataMember);
  482. } else {
  483. idx = (int) ViewState ["Items"];
  484. }
  485. if ((ds == null) && (idx == 0))
  486. return;
  487. if (headerTemplate != null)
  488. DoItem (-1, ListItemType.Header, null, useDataSource);
  489. // items
  490. if (ds != null) {
  491. foreach (object o in ds) {
  492. DoItemInLoop (idx, o, useDataSource);
  493. idx++;
  494. }
  495. } else {
  496. for (int i = 0; i < idx; i++) {
  497. DoItemInLoop (i, null, useDataSource);
  498. }
  499. }
  500. if (footerTemplate != null)
  501. DoItem (-1, ListItemType.Footer, null, useDataSource);
  502. ViewState ["Items"] = idx;
  503. }
  504. protected override Style CreateControlStyle ()
  505. {
  506. #if NET_2_0
  507. // not kept (directly) in the DataList ViewState
  508. return new TableStyle ();
  509. #else
  510. return new TableStyle (ViewState);
  511. #endif
  512. }
  513. protected virtual DataListItem CreateItem (int itemIndex, ListItemType itemType)
  514. {
  515. return new DataListItem (itemIndex, itemType);
  516. }
  517. protected virtual void InitializeItem (DataListItem item)
  518. {
  519. ITemplate t = null;
  520. switch (item.ItemType) {
  521. case ListItemType.Header:
  522. t = HeaderTemplate;
  523. break;
  524. case ListItemType.Footer:
  525. t = FooterTemplate;
  526. break;
  527. case ListItemType.Separator:
  528. t = SeparatorTemplate;
  529. break;
  530. case ListItemType.Item:
  531. case ListItemType.AlternatingItem:
  532. case ListItemType.SelectedItem:
  533. case ListItemType.EditItem:
  534. int index = item.ItemIndex;
  535. if (SelectedIndex == index)
  536. t = SelectedItemTemplate;
  537. else if (EditItemIndex == index)
  538. t = EditItemTemplate;
  539. else if (((index & 1) == 0) || (alternatingItemTemplate == null))
  540. t = ItemTemplate;
  541. else
  542. t = alternatingItemTemplate;
  543. break;
  544. }
  545. if (t != null)
  546. t.InstantiateIn (item);
  547. }
  548. protected override void LoadViewState (object savedState)
  549. {
  550. object[] state = (object[]) savedState;
  551. base.LoadViewState (state [0]);
  552. if (state [1] != null)
  553. ItemStyle.LoadViewState (state [1]);
  554. if (state [2] != null)
  555. SelectedItemStyle.LoadViewState (state [2]);
  556. if (state [3] != null)
  557. AlternatingItemStyle.LoadViewState (state [3]);
  558. if (state [4] != null)
  559. EditItemStyle.LoadViewState (state [4]);
  560. if (state [5] != null)
  561. SeparatorStyle.LoadViewState (state [5]);
  562. if (state [6] != null)
  563. HeaderStyle.LoadViewState (state [6]);
  564. if (state [7] != null)
  565. FooterStyle.LoadViewState (state [7]);
  566. }
  567. protected override bool OnBubbleEvent (object source, EventArgs e)
  568. {
  569. DataListCommandEventArgs dlca = (e as DataListCommandEventArgs);
  570. if (dlca == null)
  571. return false;
  572. string cn = dlca.CommandName;
  573. CultureInfo inv = CultureInfo.InvariantCulture;
  574. OnItemCommand (dlca);
  575. if (String.Compare (cn, CancelCommandName, true, inv) == 0) {
  576. OnCancelCommand (dlca);
  577. return true;
  578. } else if (String.Compare (cn, DeleteCommandName, true, inv) == 0) {
  579. OnDeleteCommand (dlca);
  580. return true;
  581. } else if (String.Compare (cn, EditCommandName, true, inv) == 0) {
  582. OnEditCommand (dlca);
  583. return true;
  584. } else if (String.Compare (cn, SelectCommandName, true, inv) == 0) {
  585. OnSelectedIndexChanged (dlca);
  586. return true;
  587. } else if (String.Compare (cn, UpdateCommandName, true, inv) == 0) {
  588. OnUpdateCommand (dlca);
  589. return true;
  590. }
  591. return false;
  592. }
  593. protected virtual void OnCancelCommand (DataListCommandEventArgs e)
  594. {
  595. DataListCommandEventHandler cancelCommand = (DataListCommandEventHandler) Events [cancelCommandEvent];
  596. if (cancelCommand != null)
  597. cancelCommand (this, e);
  598. }
  599. protected virtual void OnDeleteCommand (DataListCommandEventArgs e)
  600. {
  601. DataListCommandEventHandler deleteCommand = (DataListCommandEventHandler) Events [deleteCommandEvent];
  602. if (deleteCommand != null)
  603. deleteCommand (this, e);
  604. }
  605. protected virtual void OnEditCommand (DataListCommandEventArgs e)
  606. {
  607. DataListCommandEventHandler editCommand = (DataListCommandEventHandler) Events [editCommandEvent];
  608. if (editCommand != null)
  609. editCommand (this, e);
  610. }
  611. #if NET_2_0
  612. protected internal override void OnInit (EventArgs e)
  613. {
  614. // EditItemIndex and SelectedIndex now use the Control State (i.e not the View State)
  615. Page.RegisterRequiresControlState (this);
  616. base.OnInit (e);
  617. }
  618. #endif
  619. protected virtual void OnItemCommand (DataListCommandEventArgs e)
  620. {
  621. DataListCommandEventHandler itemCommand = (DataListCommandEventHandler) Events [itemCommandEvent];
  622. if (itemCommand != null)
  623. itemCommand (this, e);
  624. }
  625. protected virtual void OnItemCreated (DataListItemEventArgs e)
  626. {
  627. DataListItemEventHandler itemCreated = (DataListItemEventHandler) Events [itemCreatedEvent];
  628. if (itemCreated != null)
  629. itemCreated (this, e);
  630. }
  631. protected virtual void OnItemDataBound (DataListItemEventArgs e)
  632. {
  633. DataListItemEventHandler itemDataBound = (DataListItemEventHandler) Events [itemDataBoundEvent];
  634. if (itemDataBound != null)
  635. itemDataBound (this, e);
  636. }
  637. protected virtual void OnUpdateCommand (DataListCommandEventArgs e)
  638. {
  639. DataListCommandEventHandler updateCommand = (DataListCommandEventHandler) Events [updateCommandEvent];
  640. if (updateCommand != null)
  641. updateCommand (this, e);
  642. }
  643. protected override void PrepareControlHierarchy ()
  644. {
  645. }
  646. #if NET_2_0
  647. protected internal
  648. #else
  649. protected
  650. #endif
  651. override void RenderContents (HtmlTextWriter writer)
  652. {
  653. RepeatInfo ri = new RepeatInfo ();
  654. ri.RepeatColumns = RepeatColumns;
  655. ri.RepeatDirection = RepeatDirection;
  656. ri.RepeatLayout = RepeatLayout;
  657. /*
  658. // debugging stuff that I prefer to keep for a while
  659. Console.WriteLine ("RepeatColumns {0}", ri.RepeatColumns);
  660. Console.WriteLine ("RepeatDirection {0}", ri.RepeatDirection);
  661. Console.WriteLine ("RepeatLayout {0}", ri.RepeatLayout);
  662. Console.WriteLine ("OuterTableImplied {0}", ExtractTemplateRows);
  663. Console.WriteLine ("IRepeatInfoUser.HasFooter {0}", (ShowFooter && (footerTemplate != null)));
  664. Console.WriteLine ("IRepeatInfoUser.HasHeader {0}", (ShowHeader && (headerTemplate != null)));
  665. Console.WriteLine ("IRepeatInfoUser.HasSeparators {0}", (separatorTemplate != null));
  666. Console.WriteLine ("IRepeatInfoUser.RepeatedItemCount {0}", Items.Count);
  667. for (int i=0; i < Items.Count; i++) {
  668. DataListItem dli = Items [i];
  669. Console.WriteLine ("{0}: Index {1}, Type {2}", i, dli.ItemIndex, dli.ItemType);
  670. }
  671. */
  672. bool extract = ExtractTemplateRows;
  673. if (extract) {
  674. ri.OuterTableImplied = true;
  675. writer.AddAttribute (HtmlTextWriterAttribute.Id, ID);
  676. if (ControlStyleCreated) {
  677. ControlStyle.AddAttributesToRender (writer);
  678. }
  679. writer.RenderBeginTag (HtmlTextWriterTag.Table);
  680. ri.RenderRepeater (writer, this, TableStyle, this);
  681. writer.RenderEndTag ();
  682. } else {
  683. ri.RenderRepeater (writer, this, TableStyle, this);
  684. }
  685. }
  686. protected override object SaveViewState ()
  687. {
  688. #if NET_2_0
  689. object[] state = new object [9];
  690. // FIXME: what's new in slot #0 ?
  691. state[8] = base.SaveViewState ();
  692. #else
  693. object[] state = new object [8];
  694. state[0] = base.SaveViewState ();
  695. #endif
  696. if (itemStyle != null)
  697. state [1] = itemStyle.SaveViewState ();
  698. if (selectedItemStyle != null)
  699. state [2] = selectedItemStyle.SaveViewState ();
  700. if (alternatingItemStyle != null)
  701. state [3] = alternatingItemStyle.SaveViewState ();
  702. if (editItemStyle != null)
  703. state [4] = editItemStyle.SaveViewState ();
  704. if (separatorStyle != null)
  705. state [5] = separatorStyle.SaveViewState ();
  706. if (headerStyle != null)
  707. state [6] = headerStyle.SaveViewState ();
  708. if (footerStyle != null)
  709. state [7] = footerStyle.SaveViewState ();
  710. return state;
  711. }
  712. protected override void TrackViewState ()
  713. {
  714. base.TrackViewState ();
  715. if (alternatingItemStyle != null)
  716. alternatingItemStyle.TrackViewState ();
  717. if (editItemStyle != null)
  718. editItemStyle.TrackViewState ();
  719. if (footerStyle != null)
  720. footerStyle.TrackViewState ();
  721. if (headerStyle != null)
  722. headerStyle.TrackViewState ();
  723. if (itemStyle != null)
  724. itemStyle.TrackViewState ();
  725. if (selectedItemStyle != null)
  726. selectedItemStyle.TrackViewState ();
  727. if (separatorStyle != null)
  728. separatorStyle.TrackViewState ();
  729. }
  730. [WebSysDescription ("")]
  731. [WebCategory ("Action")]
  732. public event DataListCommandEventHandler CancelCommand {
  733. add { Events.AddHandler (cancelCommandEvent, value); }
  734. remove { Events.RemoveHandler (cancelCommandEvent, value); }
  735. }
  736. [WebSysDescription ("")]
  737. [WebCategory ("Action")]
  738. public event DataListCommandEventHandler DeleteCommand {
  739. add { Events.AddHandler (deleteCommandEvent, value); }
  740. remove { Events.RemoveHandler (deleteCommandEvent, value); }
  741. }
  742. [WebSysDescription ("")]
  743. [WebCategory ("Action")]
  744. public event DataListCommandEventHandler EditCommand {
  745. add { Events.AddHandler (editCommandEvent, value); }
  746. remove { Events.RemoveHandler (editCommandEvent, value); }
  747. }
  748. [WebSysDescription ("")]
  749. [WebCategory ("Action")]
  750. public event DataListCommandEventHandler ItemCommand {
  751. add { Events.AddHandler (itemCommandEvent, value); }
  752. remove { Events.RemoveHandler (itemCommandEvent, value); }
  753. }
  754. [WebSysDescription ("")]
  755. [WebCategory ("Action")]
  756. public event DataListItemEventHandler ItemCreated {
  757. add { Events.AddHandler (itemCreatedEvent, value); }
  758. remove { Events.RemoveHandler (itemCreatedEvent, value); }
  759. }
  760. [WebSysDescription ("")]
  761. [WebCategory ("Action")]
  762. public event DataListItemEventHandler ItemDataBound {
  763. add { Events.AddHandler (itemDataBoundEvent, value); }
  764. remove { Events.RemoveHandler (itemDataBoundEvent, value); }
  765. }
  766. [WebSysDescription ("")]
  767. [WebCategory ("Action")]
  768. public event DataListCommandEventHandler UpdateCommand {
  769. add { Events.AddHandler (updateCommandEvent, value); }
  770. remove { Events.RemoveHandler (updateCommandEvent, value); }
  771. }
  772. // IRepeatInfoUser support
  773. bool IRepeatInfoUser.HasFooter {
  774. get { return (ShowFooter && (footerTemplate != null)); }
  775. }
  776. bool IRepeatInfoUser.HasHeader {
  777. get { return (ShowHeader && (headerTemplate != null)); }
  778. }
  779. bool IRepeatInfoUser.HasSeparators {
  780. get { return (separatorTemplate != null); }
  781. }
  782. // don't include header, footer and separators in the count
  783. int IRepeatInfoUser.RepeatedItemCount {
  784. get {
  785. if (idx == -1) {
  786. object o = ViewState ["Items"];
  787. idx = (o == null) ? 0 : (int) o;
  788. }
  789. return idx;
  790. }
  791. }
  792. Style IRepeatInfoUser.GetItemStyle (ListItemType itemType, int repeatIndex)
  793. {
  794. switch (itemType) {
  795. case ListItemType.Header:
  796. if (repeatIndex >= Items.Count)
  797. throw new ArgumentOutOfRangeException ("repeatIndex");
  798. return headerStyle;
  799. case ListItemType.Footer:
  800. if (repeatIndex >= Items.Count)
  801. throw new ArgumentOutOfRangeException ("repeatIndex");
  802. return footerStyle;
  803. case ListItemType.Item:
  804. case ListItemType.AlternatingItem:
  805. case ListItemType.SelectedItem:
  806. case ListItemType.EditItem:
  807. if (repeatIndex >= Items.Count)
  808. throw new ArgumentOutOfRangeException ("repeatIndex");
  809. if (SelectedIndex == repeatIndex)
  810. return selectedItemStyle;
  811. if (EditItemIndex == repeatIndex)
  812. return editItemStyle;
  813. if (((repeatIndex & 1) == 0) || (alternatingItemStyle == null))
  814. return itemStyle;
  815. // alternate style
  816. TableItemStyle alt = new TableItemStyle ();
  817. alt.CopyFrom (itemStyle);
  818. alt.CopyFrom (alternatingItemStyle);
  819. return alt;
  820. case ListItemType.Separator:
  821. if (repeatIndex >= Items.Count)
  822. throw new ArgumentOutOfRangeException ("repeatIndex");
  823. return separatorStyle;
  824. default:
  825. return null;
  826. }
  827. }
  828. // Header and Footer don't have a "real" index (-1)
  829. private DataListItem FindFirstItem (ListItemType itemType)
  830. {
  831. for (int i = 0; i < Controls.Count; i++) {
  832. DataListItem item = (Controls [i] as DataListItem);
  833. if ((item != null) && (item.ItemType == itemType))
  834. return item;
  835. }
  836. return null;
  837. }
  838. // Both Type and Index must match (e.g. Separator)
  839. private DataListItem FindSpecificItem (ListItemType itemType, int repeatIndex)
  840. {
  841. for (int i = 0; i < Controls.Count; i++) {
  842. DataListItem item = (Controls [i] as DataListItem);
  843. if ((item != null) && (item.ItemType == itemType) && (item.ItemIndex == repeatIndex))
  844. return item;
  845. }
  846. return null;
  847. }
  848. // we get call for Item even for AlternatingItem :(
  849. private DataListItem FindBestItem (int repeatIndex)
  850. {
  851. for (int i = 0; i < Controls.Count; i++) {
  852. DataListItem item = (Controls [i] as DataListItem);
  853. if ((item != null) && (item.ItemIndex == repeatIndex)) {
  854. switch (item.ItemType) {
  855. case ListItemType.Item:
  856. case ListItemType.AlternatingItem:
  857. case ListItemType.SelectedItem:
  858. case ListItemType.EditItem:
  859. return item;
  860. default:
  861. return null;
  862. }
  863. }
  864. }
  865. return null;
  866. }
  867. void IRepeatInfoUser.RenderItem (ListItemType itemType, int repeatIndex, RepeatInfo repeatInfo, HtmlTextWriter writer)
  868. {
  869. // if possible take the easy way out...
  870. if (!HasControls ())
  871. return;
  872. DataListItem item = null;
  873. switch (itemType) {
  874. case ListItemType.Header:
  875. case ListItemType.Footer:
  876. item = FindFirstItem (itemType);
  877. break;
  878. case ListItemType.Item:
  879. case ListItemType.AlternatingItem:
  880. case ListItemType.SelectedItem:
  881. case ListItemType.EditItem:
  882. item = FindBestItem (repeatIndex);
  883. break;
  884. case ListItemType.Separator:
  885. item = FindSpecificItem (itemType, repeatIndex);
  886. break;
  887. }
  888. if (item != null) {
  889. bool extract = ExtractTemplateRows;
  890. bool table = (RepeatLayout == RepeatLayout.Table);
  891. if (!table || extract) {
  892. // sadly RepeatInfo doesn't support Style for RepeatLayout.Flow
  893. Style s = (this as IRepeatInfoUser).GetItemStyle (itemType, repeatIndex);
  894. if (s != null)
  895. item.ControlStyle.CopyFrom (s);
  896. }
  897. //Console.WriteLine ("RenderItem #{0} type {1}", repeatIndex, itemType);
  898. item.RenderItem (writer, extract, table);
  899. } else {
  900. //Console.WriteLine ("Couldn't find #{0} type {1} out of {2} items / {3} controls", repeatIndex, itemType, Items.Count, Controls.Count);
  901. }
  902. }
  903. }
  904. }