DataList.cs 31 KB

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