DataList.cs 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064
  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. #if NET_2_0
  122. get { return editIndex; }
  123. set {
  124. if (value < -1)
  125. throw new ArgumentOutOfRangeException ("EditItemIndex", "< -1");
  126. editIndex = value;
  127. }
  128. #else
  129. get {
  130. object o = ViewState ["EditItemIndex"];
  131. return (o == null) ? -1 : (int) o;
  132. }
  133. set {
  134. if (value < -1)
  135. throw new ArgumentOutOfRangeException ("EditItemIndex", "< -1");
  136. ViewState ["EditItemIndex"] = value;
  137. }
  138. #endif
  139. }
  140. [DefaultValue (null)]
  141. [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
  142. [NotifyParentProperty (true)]
  143. [PersistenceMode (PersistenceMode.InnerProperty)]
  144. [WebSysDescription ("")]
  145. [WebCategory ("Style")]
  146. public virtual TableItemStyle EditItemStyle {
  147. get {
  148. if (editItemStyle == null) {
  149. editItemStyle = new TableItemStyle ();
  150. if (IsTrackingViewState) {
  151. editItemStyle.TrackViewState ();
  152. }
  153. }
  154. return editItemStyle;
  155. }
  156. }
  157. [Browsable (false)]
  158. [DefaultValue (null)]
  159. [TemplateContainer (typeof (DataListItem))]
  160. [PersistenceMode (PersistenceMode.InnerProperty)]
  161. [WebSysDescription ("")]
  162. [WebCategory ("Style")]
  163. public virtual ITemplate EditItemTemplate {
  164. get { return editItemTemplate; }
  165. set { editItemTemplate = value; }
  166. }
  167. [DefaultValue (false)]
  168. [WebSysDescription ("")]
  169. [WebCategory ("Misc")]
  170. public virtual bool ExtractTemplateRows {
  171. get {
  172. object o = ViewState ["ExtractTemplateRows"];
  173. return (o == null) ? false : (bool) o;
  174. }
  175. set { ViewState ["ExtractTemplateRows"] = value; }
  176. }
  177. [DefaultValue (null)]
  178. [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
  179. [NotifyParentProperty (true)]
  180. [PersistenceMode (PersistenceMode.InnerProperty)]
  181. [WebSysDescription ("")]
  182. [WebCategory ("Style")]
  183. public virtual TableItemStyle FooterStyle {
  184. get {
  185. if (footerStyle == null) {
  186. footerStyle = new TableItemStyle ();
  187. if (IsTrackingViewState) {
  188. footerStyle.TrackViewState ();
  189. }
  190. }
  191. return footerStyle;
  192. }
  193. }
  194. [Browsable (false)]
  195. [DefaultValue (null)]
  196. [TemplateContainer (typeof (DataListItem))]
  197. [PersistenceMode (PersistenceMode.InnerProperty)]
  198. [WebSysDescription ("")]
  199. [WebCategory ("Style")]
  200. public virtual ITemplate FooterTemplate {
  201. get { return footerTemplate; }
  202. set { footerTemplate = value; }
  203. }
  204. // yes! they do NOT match in fx1.1
  205. [DefaultValue (GridLines.None)]
  206. public override GridLines GridLines {
  207. get {
  208. if (!ControlStyleCreated) {
  209. #if NET_2_0
  210. return GridLines.None;
  211. #else
  212. return GridLines.Both;
  213. #endif
  214. }
  215. return TableStyle.GridLines;
  216. }
  217. set { TableStyle.GridLines = value; }
  218. }
  219. [DefaultValue (null)]
  220. [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
  221. [NotifyParentProperty (true)]
  222. [PersistenceMode (PersistenceMode.InnerProperty)]
  223. [WebSysDescription ("")]
  224. [WebCategory ("Style")]
  225. public virtual TableItemStyle HeaderStyle {
  226. get {
  227. if (headerStyle == null) {
  228. headerStyle = new TableItemStyle ();
  229. if (IsTrackingViewState) {
  230. headerStyle.TrackViewState ();
  231. }
  232. }
  233. return headerStyle;
  234. }
  235. }
  236. [Browsable (false)]
  237. [DefaultValue (null)]
  238. [TemplateContainer (typeof (DataListItem))]
  239. [PersistenceMode (PersistenceMode.InnerProperty)]
  240. [WebSysDescription ("")]
  241. [WebCategory ("Style")]
  242. public virtual ITemplate HeaderTemplate {
  243. get { return headerTemplate; }
  244. set { headerTemplate = value; }
  245. }
  246. [Browsable (false)]
  247. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  248. [WebSysDescription ("")]
  249. [WebCategory ("Style")]
  250. public virtual DataListItemCollection Items {
  251. get {
  252. if (items == null)
  253. items = new DataListItemCollection (ItemList);
  254. return items;
  255. }
  256. }
  257. [DefaultValue (null)]
  258. [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
  259. [NotifyParentProperty (true)]
  260. [PersistenceMode (PersistenceMode.InnerProperty)]
  261. [WebSysDescription ("")]
  262. [WebCategory ("Style")]
  263. public virtual TableItemStyle ItemStyle {
  264. get {
  265. if (itemStyle == null) {
  266. itemStyle = new TableItemStyle ();
  267. if (IsTrackingViewState) {
  268. itemStyle.TrackViewState ();
  269. }
  270. }
  271. return itemStyle;
  272. }
  273. }
  274. [Browsable (false)]
  275. [DefaultValue (null)]
  276. [TemplateContainer (typeof (DataListItem))]
  277. [PersistenceMode (PersistenceMode.InnerProperty)]
  278. [WebSysDescription ("")]
  279. [WebCategory ("Style")]
  280. public virtual ITemplate ItemTemplate {
  281. get { return itemTemplate; }
  282. set { itemTemplate = value; }
  283. }
  284. #if ONLY_1_1
  285. [Bindable (true)]
  286. #endif
  287. [DefaultValue (0)]
  288. [WebSysDescription ("")]
  289. [WebCategory ("Layout")]
  290. public virtual int RepeatColumns {
  291. get {
  292. object o = ViewState ["RepeatColumns"];
  293. return (o == null) ? 0 : (int) o;
  294. }
  295. set { ViewState ["RepeatColumns"] = value; }
  296. }
  297. #if ONLY_1_1
  298. [Bindable (true)]
  299. #endif
  300. [DefaultValue (RepeatDirection.Vertical)]
  301. [WebSysDescription ("")]
  302. [WebCategory ("Layout")]
  303. public virtual RepeatDirection RepeatDirection {
  304. get {
  305. object o = ViewState ["RepeatDirection"];
  306. return (o == null) ? RepeatDirection.Vertical : (RepeatDirection) o;
  307. }
  308. set { ViewState ["RepeatDirection"] = value; }
  309. }
  310. #if ONLY_1_1
  311. [Bindable (true)]
  312. #endif
  313. [DefaultValue (RepeatLayout.Table)]
  314. [WebSysDescription ("")]
  315. [WebCategory ("Layout")]
  316. public virtual RepeatLayout RepeatLayout {
  317. get {
  318. object o = ViewState ["RepeatLayout"];
  319. return (o == null) ? RepeatLayout.Table : (RepeatLayout) o;
  320. }
  321. set { ViewState ["RepeatLayout"] = value; }
  322. }
  323. [Bindable (true)]
  324. [DefaultValue (-1)]
  325. [WebSysDescription ("")]
  326. [WebCategory ("Layout")]
  327. public virtual int SelectedIndex {
  328. #if NET_2_0
  329. get { return selectedIndex; }
  330. set {
  331. if (value < -1)
  332. throw new ArgumentOutOfRangeException ("SelectedIndex", "< -1");
  333. selectedIndex = value;
  334. }
  335. #else
  336. get {
  337. object o = ViewState ["SelectedIndex"];
  338. return (o == null) ? -1 : (int) o;
  339. }
  340. set {
  341. if (value < -1)
  342. throw new ArgumentOutOfRangeException ("SelectedIndex", "< -1");
  343. ViewState ["SelectedIndex"] = value;
  344. }
  345. #endif
  346. }
  347. [Browsable (false)]
  348. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  349. [WebSysDescription ("")]
  350. [WebCategory ("Layout")]
  351. public virtual DataListItem SelectedItem {
  352. get {
  353. if (SelectedIndex < 0)
  354. return null;
  355. if (SelectedIndex >= Items.Count)
  356. throw new ArgumentOutOfRangeException ("SelectedItem", ">= Items.Count");
  357. return items [SelectedIndex];
  358. }
  359. }
  360. [DefaultValue (null)]
  361. [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
  362. [NotifyParentProperty (true)]
  363. [PersistenceMode (PersistenceMode.InnerProperty)]
  364. [WebSysDescription ("")]
  365. [WebCategory ("Style")]
  366. public virtual TableItemStyle SelectedItemStyle {
  367. get {
  368. if (selectedItemStyle == null) {
  369. selectedItemStyle = new TableItemStyle ();
  370. if (IsTrackingViewState) {
  371. selectedItemStyle.TrackViewState ();
  372. }
  373. }
  374. return selectedItemStyle;
  375. }
  376. }
  377. [Browsable (false)]
  378. [DefaultValue (null)]
  379. [TemplateContainer (typeof (DataListItem))]
  380. [PersistenceMode (PersistenceMode.InnerProperty)]
  381. [WebSysDescription ("")]
  382. [WebCategory ("Style")]
  383. public virtual ITemplate SelectedItemTemplate {
  384. get { return selectedItemTemplate; }
  385. set { selectedItemTemplate = value; }
  386. }
  387. [DefaultValue (null)]
  388. [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
  389. [NotifyParentProperty (true)]
  390. [PersistenceMode (PersistenceMode.InnerProperty)]
  391. [WebSysDescription ("")]
  392. [WebCategory ("Style")]
  393. public virtual TableItemStyle SeparatorStyle {
  394. get {
  395. if (separatorStyle == null) {
  396. separatorStyle = new TableItemStyle ();
  397. if (IsTrackingViewState) {
  398. separatorStyle.TrackViewState ();
  399. }
  400. }
  401. return separatorStyle;
  402. }
  403. }
  404. [Browsable (false)]
  405. [DefaultValue (null)]
  406. [TemplateContainer (typeof (DataListItem))]
  407. [PersistenceMode (PersistenceMode.InnerProperty)]
  408. [WebSysDescription ("")]
  409. [WebCategory ("Style")]
  410. public virtual ITemplate SeparatorTemplate {
  411. get { return separatorTemplate; }
  412. set { separatorTemplate = value; }
  413. }
  414. #if ONLY_1_1
  415. [Bindable (true)]
  416. #endif
  417. [DefaultValue (true)]
  418. [WebSysDescription ("")]
  419. [WebCategory ("Appearance")]
  420. public virtual bool ShowFooter {
  421. get {
  422. object o = ViewState ["ShowFooter"];
  423. return (o == null) ? true : (bool) o;
  424. }
  425. set { ViewState ["ShowFooter"] = value; }
  426. }
  427. #if ONLY_1_1
  428. [Bindable (true)]
  429. #endif
  430. [DefaultValue (true)]
  431. [WebSysDescription ("")]
  432. [WebCategory ("Appearance")]
  433. public virtual bool ShowHeader {
  434. get {
  435. object o = ViewState ["ShowHeader"];
  436. return (o == null) ? true : (bool) o;
  437. }
  438. set { ViewState ["ShowHeader"] = value; }
  439. }
  440. #if NET_2_0
  441. [MonoTODO ("incomplete")]
  442. [Browsable (false)]
  443. public object SelectedValue {
  444. get {
  445. if (DataKeyField.Length == 0)
  446. throw new InvalidOperationException (Locale.GetText ("No DataKeyField present."));
  447. if ((SelectedIndex >= 0) && (selectedIndex < DataKeys.Count)) {
  448. return DataKeys [selectedIndex];
  449. }
  450. return null;
  451. }
  452. }
  453. protected override HtmlTextWriterTag TagKey {
  454. get { return HtmlTextWriterTag.Table; }
  455. }
  456. #endif
  457. private TableStyle TableStyle {
  458. // this will throw an InvalidCasException just like we need
  459. get { return (TableStyle) ControlStyle; }
  460. }
  461. private ArrayList ItemList {
  462. get {
  463. if (list == null)
  464. list = new ArrayList ();
  465. return list;
  466. }
  467. }
  468. void DoItem (int i, ListItemType t, object d, bool databind)
  469. {
  470. DataListItem itm = CreateItem (i, t);
  471. itm.DataItem = d;
  472. DataListItemEventArgs e = new DataListItemEventArgs (itm);
  473. InitializeItem (itm);
  474. //
  475. // It is very important that this be called *before* data
  476. // binding. Otherwise, we won't save our state in the viewstate.
  477. //
  478. Controls.Add (itm);
  479. if (i != -1)
  480. ItemList.Add (itm);
  481. OnItemCreated (e);
  482. if (databind) {
  483. itm.DataBind ();
  484. OnItemDataBound (e);
  485. }
  486. }
  487. private void DoItemInLoop (int i, object d, bool databind)
  488. {
  489. if (i > 0 && SeparatorTemplate != null)
  490. DoItem (i - 1, ListItemType.Separator, null, databind);
  491. DoItem (i, i % 2 == 0 ? ListItemType.Item : ListItemType.AlternatingItem, d, databind);
  492. }
  493. protected override void CreateControlHierarchy (bool useDataSource)
  494. {
  495. Controls.Clear();
  496. IEnumerable ds = null;
  497. if (useDataSource) {
  498. idx = 0;
  499. ds = DataSourceResolver.ResolveDataSource (DataSource, DataMember);
  500. } else {
  501. idx = (int) ViewState ["Items"];
  502. }
  503. if ((ds == null) && (idx == 0))
  504. return;
  505. if (headerTemplate != null)
  506. DoItem (-1, ListItemType.Header, null, useDataSource);
  507. // items
  508. if (ds != null) {
  509. foreach (object o in ds) {
  510. DoItemInLoop (idx, o, useDataSource);
  511. idx++;
  512. }
  513. } else {
  514. for (int i = 0; i < idx; i++) {
  515. DoItemInLoop (i, null, useDataSource);
  516. }
  517. }
  518. if (footerTemplate != null)
  519. DoItem (-1, ListItemType.Footer, null, useDataSource);
  520. ViewState ["Items"] = idx;
  521. }
  522. protected override Style CreateControlStyle ()
  523. {
  524. #if NET_2_0
  525. // not kept (directly) in the DataList ViewState
  526. return new TableStyle ();
  527. #else
  528. return new TableStyle (ViewState);
  529. #endif
  530. }
  531. protected virtual DataListItem CreateItem (int itemIndex, ListItemType itemType)
  532. {
  533. return new DataListItem (itemIndex, itemType);
  534. }
  535. protected virtual void InitializeItem (DataListItem item)
  536. {
  537. ITemplate t = null;
  538. switch (item.ItemType) {
  539. case ListItemType.Header:
  540. t = HeaderTemplate;
  541. break;
  542. case ListItemType.Footer:
  543. t = FooterTemplate;
  544. break;
  545. case ListItemType.Separator:
  546. t = SeparatorTemplate;
  547. break;
  548. case ListItemType.Item:
  549. case ListItemType.AlternatingItem:
  550. case ListItemType.SelectedItem:
  551. case ListItemType.EditItem:
  552. int index = item.ItemIndex;
  553. if (SelectedIndex == index)
  554. t = SelectedItemTemplate;
  555. else if (EditItemIndex == index)
  556. t = EditItemTemplate;
  557. else if (((index & 1) == 0) || (alternatingItemTemplate == null))
  558. t = ItemTemplate;
  559. else
  560. t = alternatingItemTemplate;
  561. break;
  562. }
  563. if (t != null)
  564. t.InstantiateIn (item);
  565. }
  566. protected override void LoadViewState (object savedState)
  567. {
  568. object[] state = (object[]) savedState;
  569. base.LoadViewState (state [0]);
  570. if (state [1] != null)
  571. ItemStyle.LoadViewState (state [1]);
  572. if (state [2] != null)
  573. SelectedItemStyle.LoadViewState (state [2]);
  574. if (state [3] != null)
  575. AlternatingItemStyle.LoadViewState (state [3]);
  576. if (state [4] != null)
  577. EditItemStyle.LoadViewState (state [4]);
  578. if (state [5] != null)
  579. SeparatorStyle.LoadViewState (state [5]);
  580. if (state [6] != null)
  581. HeaderStyle.LoadViewState (state [6]);
  582. if (state [7] != null)
  583. FooterStyle.LoadViewState (state [7]);
  584. }
  585. #if NET_2_0
  586. protected internal override void LoadControlState (object savedState)
  587. {
  588. // FIXME: what's in Triplet.First ?
  589. // ??? maybe a some space for base.LoadControlState ???
  590. if (savedState == null) {
  591. // reset to default values
  592. editIndex = -1;
  593. selectedIndex = -1;
  594. } else {
  595. Triplet t = (Triplet) savedState;
  596. if (t.Second == null) {
  597. editIndex = -1;
  598. } else {
  599. editIndex = (int) t.Second;
  600. }
  601. if (t.Third == null) {
  602. selectedIndex = -1;
  603. } else {
  604. selectedIndex = (int) t.Third;
  605. }
  606. }
  607. }
  608. protected internal override object SaveControlState ()
  609. {
  610. bool e = (editIndex == -1);
  611. bool s = (selectedIndex == -1);
  612. if (e && s)
  613. return null;
  614. Triplet t = new Triplet ();
  615. if (!e)
  616. t.Second = editIndex;
  617. if (!s)
  618. t.Third = selectedIndex;
  619. return (object) t;
  620. }
  621. #endif
  622. protected override bool OnBubbleEvent (object source, EventArgs e)
  623. {
  624. DataListCommandEventArgs dlca = (e as DataListCommandEventArgs);
  625. if (dlca == null)
  626. return false;
  627. string cn = dlca.CommandName;
  628. CultureInfo inv = CultureInfo.InvariantCulture;
  629. if (String.Compare (cn, CancelCommandName, true, inv) == 0) {
  630. OnCancelCommand (dlca);
  631. return true;
  632. } else if (String.Compare (cn, DeleteCommandName, true, inv) == 0) {
  633. OnDeleteCommand (dlca);
  634. return true;
  635. } else if (String.Compare (cn, EditCommandName, true, inv) == 0) {
  636. OnEditCommand (dlca);
  637. return true;
  638. } else if (String.Compare (cn, SelectCommandName, true, inv) == 0) {
  639. OnSelectedIndexChanged (dlca);
  640. return true;
  641. } else if (String.Compare (cn, UpdateCommandName, true, inv) == 0) {
  642. OnUpdateCommand (dlca);
  643. return true;
  644. } else if (String.Compare (cn, "ITEM", true, inv) == 0) {
  645. OnItemCommand (dlca);
  646. return true;
  647. }
  648. return false;
  649. }
  650. protected virtual void OnCancelCommand (DataListCommandEventArgs e)
  651. {
  652. DataListCommandEventHandler cancelCommand = (DataListCommandEventHandler) Events [cancelCommandEvent];
  653. if (cancelCommand != null)
  654. cancelCommand (this, e);
  655. }
  656. protected virtual void OnDeleteCommand (DataListCommandEventArgs e)
  657. {
  658. DataListCommandEventHandler deleteCommand = (DataListCommandEventHandler) Events [deleteCommandEvent];
  659. if (deleteCommand != null)
  660. deleteCommand (this, e);
  661. }
  662. protected virtual void OnEditCommand (DataListCommandEventArgs e)
  663. {
  664. DataListCommandEventHandler editCommand = (DataListCommandEventHandler) Events [editCommandEvent];
  665. if (editCommand != null)
  666. editCommand (this, e);
  667. }
  668. #if NET_2_0
  669. protected internal override void OnInit (EventArgs e)
  670. {
  671. // EditItemIndex and SelectedIndex now use the Control State (i.e not the View State)
  672. Page.RegisterRequiresControlState (this);
  673. base.OnInit (e);
  674. }
  675. #endif
  676. protected virtual void OnItemCommand (DataListCommandEventArgs e)
  677. {
  678. DataListCommandEventHandler itemCommand = (DataListCommandEventHandler) Events [itemCommandEvent];
  679. if (itemCommand != null)
  680. itemCommand (this, e);
  681. }
  682. protected virtual void OnItemCreated (DataListItemEventArgs e)
  683. {
  684. DataListItemEventHandler itemCreated = (DataListItemEventHandler) Events [itemCreatedEvent];
  685. if (itemCreated != null)
  686. itemCreated (this, e);
  687. }
  688. protected virtual void OnItemDataBound (DataListItemEventArgs e)
  689. {
  690. DataListItemEventHandler itemDataBound = (DataListItemEventHandler) Events [itemDataBoundEvent];
  691. if (itemDataBound != null)
  692. itemDataBound (this, e);
  693. }
  694. protected virtual void OnUpdateCommand (DataListCommandEventArgs e)
  695. {
  696. DataListCommandEventHandler updateCommand = (DataListCommandEventHandler) Events [updateCommandEvent];
  697. if (updateCommand != null)
  698. updateCommand (this, e);
  699. }
  700. protected override void PrepareControlHierarchy ()
  701. {
  702. }
  703. #if NET_2_0
  704. protected internal
  705. #else
  706. protected
  707. #endif
  708. override void RenderContents (HtmlTextWriter writer)
  709. {
  710. RepeatInfo ri = new RepeatInfo ();
  711. ri.RepeatColumns = RepeatColumns;
  712. ri.RepeatDirection = RepeatDirection;
  713. ri.RepeatLayout = RepeatLayout;
  714. /*
  715. // debugging stuff that I prefer to keep for a while
  716. Console.WriteLine ("RepeatColumns {0}", ri.RepeatColumns);
  717. Console.WriteLine ("RepeatDirection {0}", ri.RepeatDirection);
  718. Console.WriteLine ("RepeatLayout {0}", ri.RepeatLayout);
  719. Console.WriteLine ("OuterTableImplied {0}", ExtractTemplateRows);
  720. Console.WriteLine ("IRepeatInfoUser.HasFooter {0}", (ShowFooter && (footerTemplate != null)));
  721. Console.WriteLine ("IRepeatInfoUser.HasHeader {0}", (ShowHeader && (headerTemplate != null)));
  722. Console.WriteLine ("IRepeatInfoUser.HasSeparators {0}", (separatorTemplate != null));
  723. Console.WriteLine ("IRepeatInfoUser.RepeatedItemCount {0}", Items.Count);
  724. for (int i=0; i < Items.Count; i++) {
  725. DataListItem dli = Items [i];
  726. Console.WriteLine ("{0}: Index {1}, Type {2}", i, dli.ItemIndex, dli.ItemType);
  727. }
  728. */
  729. bool extract = ExtractTemplateRows;
  730. if (extract) {
  731. ri.OuterTableImplied = true;
  732. writer.AddAttribute (HtmlTextWriterAttribute.Id, ID);
  733. if (ControlStyleCreated) {
  734. ControlStyle.AddAttributesToRender (writer);
  735. }
  736. writer.RenderBeginTag (HtmlTextWriterTag.Table);
  737. ri.RenderRepeater (writer, this, TableStyle, this);
  738. writer.RenderEndTag ();
  739. } else {
  740. ri.RenderRepeater (writer, this, TableStyle, this);
  741. }
  742. }
  743. protected override object SaveViewState ()
  744. {
  745. #if NET_2_0
  746. object[] state = new object [9];
  747. // FIXME: what's new in slot #0 ?
  748. state[8] = base.SaveViewState ();
  749. #else
  750. object[] state = new object [8];
  751. state[0] = base.SaveViewState ();
  752. #endif
  753. if (itemStyle != null)
  754. state [1] = itemStyle.SaveViewState ();
  755. if (selectedItemStyle != null)
  756. state [2] = selectedItemStyle.SaveViewState ();
  757. if (alternatingItemStyle != null)
  758. state [3] = alternatingItemStyle.SaveViewState ();
  759. if (editItemStyle != null)
  760. state [4] = editItemStyle.SaveViewState ();
  761. if (separatorStyle != null)
  762. state [5] = separatorStyle.SaveViewState ();
  763. if (headerStyle != null)
  764. state [6] = headerStyle.SaveViewState ();
  765. if (footerStyle != null)
  766. state [7] = footerStyle.SaveViewState ();
  767. return state;
  768. }
  769. protected override void TrackViewState ()
  770. {
  771. base.TrackViewState ();
  772. if (alternatingItemStyle != null)
  773. alternatingItemStyle.TrackViewState ();
  774. if (editItemStyle != null)
  775. editItemStyle.TrackViewState ();
  776. if (footerStyle != null)
  777. footerStyle.TrackViewState ();
  778. if (headerStyle != null)
  779. headerStyle.TrackViewState ();
  780. if (itemStyle != null)
  781. itemStyle.TrackViewState ();
  782. if (selectedItemStyle != null)
  783. selectedItemStyle.TrackViewState ();
  784. if (separatorStyle != null)
  785. separatorStyle.TrackViewState ();
  786. }
  787. [WebSysDescription ("")]
  788. [WebCategory ("Action")]
  789. public event DataListCommandEventHandler CancelCommand {
  790. add { Events.AddHandler (cancelCommandEvent, value); }
  791. remove { Events.RemoveHandler (cancelCommandEvent, value); }
  792. }
  793. [WebSysDescription ("")]
  794. [WebCategory ("Action")]
  795. public event DataListCommandEventHandler DeleteCommand {
  796. add { Events.AddHandler (deleteCommandEvent, value); }
  797. remove { Events.RemoveHandler (deleteCommandEvent, value); }
  798. }
  799. [WebSysDescription ("")]
  800. [WebCategory ("Action")]
  801. public event DataListCommandEventHandler EditCommand {
  802. add { Events.AddHandler (editCommandEvent, value); }
  803. remove { Events.RemoveHandler (editCommandEvent, value); }
  804. }
  805. [WebSysDescription ("")]
  806. [WebCategory ("Action")]
  807. public event DataListCommandEventHandler ItemCommand {
  808. add { Events.AddHandler (itemCommandEvent, value); }
  809. remove { Events.RemoveHandler (itemCommandEvent, value); }
  810. }
  811. [WebSysDescription ("")]
  812. [WebCategory ("Action")]
  813. public event DataListItemEventHandler ItemCreated {
  814. add { Events.AddHandler (itemCreatedEvent, value); }
  815. remove { Events.RemoveHandler (itemCreatedEvent, value); }
  816. }
  817. [WebSysDescription ("")]
  818. [WebCategory ("Action")]
  819. public event DataListItemEventHandler ItemDataBound {
  820. add { Events.AddHandler (itemDataBoundEvent, value); }
  821. remove { Events.RemoveHandler (itemDataBoundEvent, value); }
  822. }
  823. [WebSysDescription ("")]
  824. [WebCategory ("Action")]
  825. public event DataListCommandEventHandler UpdateCommand {
  826. add { Events.AddHandler (updateCommandEvent, value); }
  827. remove { Events.RemoveHandler (updateCommandEvent, value); }
  828. }
  829. // IRepeatInfoUser support
  830. bool IRepeatInfoUser.HasFooter {
  831. get { return (ShowFooter && (footerTemplate != null)); }
  832. }
  833. bool IRepeatInfoUser.HasHeader {
  834. get { return (ShowHeader && (headerTemplate != null)); }
  835. }
  836. bool IRepeatInfoUser.HasSeparators {
  837. get { return (separatorTemplate != null); }
  838. }
  839. // don't include header, footer and separators in the count
  840. int IRepeatInfoUser.RepeatedItemCount {
  841. get {
  842. if (idx == -1) {
  843. object o = ViewState ["Items"];
  844. idx = (o == null) ? 0 : (int) o;
  845. }
  846. return idx;
  847. }
  848. }
  849. Style IRepeatInfoUser.GetItemStyle (ListItemType itemType, int repeatIndex)
  850. {
  851. switch (itemType) {
  852. case ListItemType.Header:
  853. if (repeatIndex >= Items.Count)
  854. throw new ArgumentOutOfRangeException ("repeatIndex");
  855. return headerStyle;
  856. case ListItemType.Footer:
  857. if (repeatIndex >= Items.Count)
  858. throw new ArgumentOutOfRangeException ("repeatIndex");
  859. return footerStyle;
  860. case ListItemType.Item:
  861. case ListItemType.AlternatingItem:
  862. case ListItemType.SelectedItem:
  863. case ListItemType.EditItem:
  864. if (repeatIndex >= Items.Count)
  865. throw new ArgumentOutOfRangeException ("repeatIndex");
  866. if (SelectedIndex == repeatIndex)
  867. return selectedItemStyle;
  868. if (EditItemIndex == repeatIndex)
  869. return editItemStyle;
  870. if (((repeatIndex & 1) == 0) || (alternatingItemStyle == null))
  871. return itemStyle;
  872. // alternate style
  873. TableItemStyle alt = new TableItemStyle ();
  874. alt.CopyFrom (itemStyle);
  875. alt.CopyFrom (alternatingItemStyle);
  876. return alt;
  877. case ListItemType.Separator:
  878. if (repeatIndex >= Items.Count)
  879. throw new ArgumentOutOfRangeException ("repeatIndex");
  880. return separatorStyle;
  881. default:
  882. return null;
  883. }
  884. }
  885. // Header and Footer don't have a "real" index (-1)
  886. private DataListItem FindFirstItem (ListItemType itemType)
  887. {
  888. for (int i = 0; i < Controls.Count; i++) {
  889. DataListItem item = (Controls [i] as DataListItem);
  890. if ((item != null) && (item.ItemType == itemType))
  891. return item;
  892. }
  893. return null;
  894. }
  895. // Both Type and Index must match (e.g. Separator)
  896. private DataListItem FindSpecificItem (ListItemType itemType, int repeatIndex)
  897. {
  898. for (int i = 0; i < Controls.Count; i++) {
  899. DataListItem item = (Controls [i] as DataListItem);
  900. if ((item != null) && (item.ItemType == itemType) && (item.ItemIndex == repeatIndex))
  901. return item;
  902. }
  903. return null;
  904. }
  905. // we get call for Item even for AlternatingItem :(
  906. private DataListItem FindBestItem (int repeatIndex)
  907. {
  908. for (int i = 0; i < Controls.Count; i++) {
  909. DataListItem item = (Controls [i] as DataListItem);
  910. if ((item != null) && (item.ItemIndex == repeatIndex)) {
  911. switch (item.ItemType) {
  912. case ListItemType.Item:
  913. case ListItemType.AlternatingItem:
  914. case ListItemType.SelectedItem:
  915. case ListItemType.EditItem:
  916. return item;
  917. default:
  918. return null;
  919. }
  920. }
  921. }
  922. return null;
  923. }
  924. void IRepeatInfoUser.RenderItem (ListItemType itemType, int repeatIndex, RepeatInfo repeatInfo, HtmlTextWriter writer)
  925. {
  926. // if possible take the easy way out...
  927. if (!HasControls ())
  928. return;
  929. DataListItem item = null;
  930. switch (itemType) {
  931. case ListItemType.Header:
  932. case ListItemType.Footer:
  933. item = FindFirstItem (itemType);
  934. break;
  935. case ListItemType.Item:
  936. case ListItemType.AlternatingItem:
  937. case ListItemType.SelectedItem:
  938. case ListItemType.EditItem:
  939. item = FindBestItem (repeatIndex);
  940. break;
  941. case ListItemType.Separator:
  942. item = FindSpecificItem (itemType, repeatIndex);
  943. break;
  944. }
  945. if (item != null) {
  946. bool extract = ExtractTemplateRows;
  947. bool table = (RepeatLayout == RepeatLayout.Table);
  948. if (!table || extract) {
  949. // sadly RepeatInfo doesn't support Style for RepeatLayout.Flow
  950. Style s = (this as IRepeatInfoUser).GetItemStyle (itemType, repeatIndex);
  951. if (s != null)
  952. item.ControlStyle.CopyFrom (s);
  953. }
  954. //Console.WriteLine ("RenderItem #{0} type {1}", repeatIndex, itemType);
  955. item.RenderItem (writer, extract, table);
  956. } else {
  957. //Console.WriteLine ("Couldn't find #{0} type {1} out of {2} items / {3} controls", repeatIndex, itemType, Items.Count, Controls.Count);
  958. }
  959. }
  960. }
  961. }