* HyperLinkField.cs: fixed InitializeCell, should create link control only in data...
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / HyperLinkField.cs
1 //
2 // System.Web.UI.WebControls.HyperLinkField.cs
3 //
4 // Authors:
5 //      Lluis Sanchez Gual (lluis@novell.com)
6 //
7 // (C) 2005 Novell, Inc (http://www.novell.com)
8 //
9
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30
31 #if NET_2_0
32 using System.Collections;
33 using System.Collections.Specialized;
34 using System.Web.UI;
35 using System.ComponentModel;
36 using System.Security.Permissions;
37 using System.Reflection;
38
39 namespace System.Web.UI.WebControls {
40
41         [AspNetHostingPermissionAttribute (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
42         [AspNetHostingPermissionAttribute (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
43         public class HyperLinkField : DataControlField
44         {
45                 PropertyDescriptor textProperty;
46                 PropertyDescriptor[] urlProperties;
47                 static string[] emptyFields;
48                 
49                 public override bool Initialize (bool sortingEnabled, Control control)
50                 {
51                         return base.Initialize (sortingEnabled, control);
52                 }
53                 
54                 [EditorAttribute ("System.Web.UI.Design.WebControls.DataFieldEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
55                 [TypeConverterAttribute (typeof(StringArrayConverter))]
56                 [WebCategoryAttribute ("Data")]
57                 [DefaultValueAttribute (null)]
58                 public virtual string[] DataNavigateUrlFields {
59                         get {
60                                 object ob = ViewState ["DataNavigateUrlFields"];
61                                 if (ob != null) return (string[]) ob;
62                                 if (emptyFields == null) emptyFields = new string[0];
63                                 return emptyFields;
64                         }
65                         set {
66                                 ViewState ["DataNavigateUrlFields"] = value;
67                                 OnFieldChanged ();
68                         }
69                 }
70
71                 [DefaultValueAttribute ("")]
72                 [WebCategoryAttribute ("Data")]
73                 public virtual string DataNavigateUrlFormatString {
74                         get {
75                                 object ob = ViewState ["DataNavigateUrlFormatString"];
76                                 if (ob != null) return (string) ob;
77                                 return "";
78                         }
79                         set {
80                                 ViewState ["DataNavigateUrlFormatString"] = value;
81                                 OnFieldChanged ();
82                         }
83                 }
84
85                 [WebCategoryAttribute ("Data")]
86                 [DefaultValueAttribute ("")]
87                 [TypeConverterAttribute ("System.Web.UI.Design.DataSourceViewSchemaConverter, " + Consts.AssemblySystem_Design)]
88                 public virtual string DataTextField {
89                         get {
90                                 object ob = ViewState ["DataTextField"];
91                                 if (ob != null) return (string) ob;
92                                 return "";
93                         }
94                         set {
95                                 ViewState ["DataTextField"] = value;
96                                 OnFieldChanged ();
97                         }
98                 }
99
100                 [DefaultValueAttribute ("")]
101                 [WebCategoryAttribute ("Data")]
102                 public virtual string DataTextFormatString {
103                         get {
104                                 object ob = ViewState ["DataTextFormatString"];
105                                 if (ob != null) return (string) ob;
106                                 return "";
107                         }
108                         set {
109                                 ViewState ["DataTextFormatString"] = value;
110                                 OnFieldChanged ();
111                         }
112                 }
113
114                 [DefaultValueAttribute ("")]
115                 [EditorAttribute ("System.Web.UI.Design.UrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
116                 [UrlPropertyAttribute]
117                 [WebCategoryAttribute ("Behavior")]
118                 public virtual string NavigateUrl {
119                         get {
120                                 object ob = ViewState ["NavigateUrl"];
121                                 if (ob != null) return (string) ob;
122                                 return "";
123                         }
124                         set {
125                                 ViewState ["NavigateUrl"] = value;
126                                 OnFieldChanged ();
127                         }
128                 }
129
130                 [DefaultValueAttribute ("")]
131                 [WebCategoryAttribute ("Behavior")]
132                 [TypeConverterAttribute (typeof(TargetConverter))]
133                 public virtual string Target {
134                         get {
135                                 object ob = ViewState ["Target"];
136                                 if (ob != null) return (string) ob;
137                                 return "";
138                         }
139                         set {
140                                 ViewState ["Target"] = value;
141                                 OnFieldChanged ();
142                         }
143                 }
144
145                 [LocalizableAttribute (true)]
146                 [DefaultValueAttribute ("")]
147                 [WebCategoryAttribute ("Appearance")]
148                 public virtual string Text {
149                         get {
150                                 object ob = ViewState ["Text"];
151                                 if (ob != null) return (string) ob;
152                                 return "";
153                         }
154                         set {
155                                 ViewState ["Text"] = value;
156                                 OnFieldChanged ();
157                         }
158                 }
159                 
160                 public override void InitializeCell (DataControlFieldCell cell,
161                                                      DataControlCellType cellType, DataControlRowState rowState, int rowIndex)
162                 {
163                         base.InitializeCell (cell, cellType, rowState, rowIndex);\r
164                         if (cellType == DataControlCellType.DataCell) {\r
165                                 HyperLink link = new HyperLink ();\r
166                                 bool bind = false;\r
167 \r
168                                 if (Target.Length > 0)\r
169                                         link.Target = Target;\r
170 \r
171                                 if (DataTextField.Length > 0)\r
172                                         bind = true;\r
173                                 else\r
174                                         link.Text = Text;\r
175 \r
176                                 string [] fields = DataNavigateUrlFields;\r
177                                 if (fields.Length > 0)\r
178                                         bind = true;\r
179                                 else\r
180                                         link.NavigateUrl = NavigateUrl;\r
181 \r
182                                 if (bind && cellType == DataControlCellType.DataCell && (rowState & DataControlRowState.Insert) == 0)\r
183                                         cell.DataBinding += new EventHandler (OnDataBindField);\r
184 \r
185                                 link.ControlStyle.CopyFrom (ControlStyle);\r
186 \r
187                                 cell.Controls.Add (link);\r
188                         }
189                 }
190                 
191                 protected virtual string FormatDataNavigateUrlValue (object[] dataUrlValues)
192                 {
193                         if (dataUrlValues == null || dataUrlValues.Length == 0)
194                                 return "";
195                         else if (DataNavigateUrlFormatString.Length > 0)
196                                 return string.Format (DataNavigateUrlFormatString, dataUrlValues);
197                         else
198                                 return dataUrlValues[0].ToString ();
199                 }
200                 
201                 protected virtual string FormatDataTextValue (object dataTextValue)
202                 {
203                         if (DataTextFormatString.Length > 0)
204                                 return string.Format (DataTextFormatString, dataTextValue);
205                         else if (dataTextValue == null)
206                                 return "";
207                         else
208                                 return dataTextValue.ToString ();
209                 }
210                 
211                 void OnDataBindField (object sender, EventArgs e)
212                 {
213                         DataControlFieldCell cell = (DataControlFieldCell) sender;
214                         HyperLink link = (HyperLink) cell.Controls [0];
215                         object controlContainer = cell.BindingContainer;
216                         object item = DataBinder.GetDataItem (controlContainer);
217                         
218                         if (DataTextField.Length > 0) {
219                                 if (textProperty == null) SetupProperties (controlContainer);
220                                 link.Text = FormatDataTextValue (textProperty.GetValue (item));
221                         }
222                         
223                         string[] urlFields = DataNavigateUrlFields;
224                         if (urlFields.Length > 0) {
225                                 if (urlProperties == null) SetupProperties (controlContainer);
226                                 object[] dataUrlValues = new object [urlFields.Length];
227                                 for (int n=0; n<dataUrlValues.Length; n++)
228                                         dataUrlValues [n] = urlProperties [n].GetValue (item);
229                                 link.NavigateUrl = FormatDataNavigateUrlValue (dataUrlValues);
230                         }
231                 }
232                 
233                 void SetupProperties (object controlContainer)
234                 {
235                         object item = DataBinder.GetDataItem (controlContainer);
236                         PropertyDescriptorCollection props = TypeDescriptor.GetProperties (item); 
237                         
238                         if (DataTextField.Length > 0) {
239                                 textProperty = props [DataTextField];
240                                 if (textProperty == null)
241                                         new InvalidOperationException ("Property '" + DataTextField + "' not found in object of type " + item.GetType());
242                         }
243                         
244                         string[] urlFields = DataNavigateUrlFields;
245                         if (urlFields.Length > 0) {
246                                 urlProperties = new PropertyDescriptor [urlFields.Length];
247                                 for (int n=0; n<urlFields.Length; n++) {
248                                         PropertyDescriptor prop = props [urlFields [n]];
249                                         if (prop == null)
250                                                 new InvalidOperationException ("Property '" + urlFields [n] + "' not found in object of type " + item.GetType());
251                                         urlProperties [n] = prop;
252                                 }
253                         }
254                 }
255                 
256                 protected override DataControlField CreateField ()
257                 {
258                         return new HyperLinkField ();
259                 }
260                 
261                 protected override void CopyProperties (DataControlField newField)
262                 {
263                         base.CopyProperties (newField);
264                         HyperLinkField field = (HyperLinkField) newField;
265                         field.DataNavigateUrlFields = DataNavigateUrlFields;
266                         field.DataNavigateUrlFormatString = DataNavigateUrlFormatString;
267                         field.DataTextField = DataTextField;
268                         field.DataTextFormatString = DataTextFormatString;
269                         field.NavigateUrl = NavigateUrl;
270                         field.Target = Target;
271                         field.Text = Text;
272                 }
273                 
274                 public override void ValidateSupportsCallback ()
275                 {
276                 }
277         }
278 }
279 #endif