private void RenderEditor(HtmlTextWriter writer) { if (_propertyDescriptor.IsReadOnly && ParentGrid.HideReadOnly) { return; } if (ParentGrid.HiddenProperties.Contains(Name)) { return; } //writer.Write(@"<table width=""100%"">"); //writer.Write(@"<tr class=""PropertyGridPropertyRow"" align=""left"">"); var access = string.Empty; var displayedName = DisplayName; var propertyUrl = string.Empty; if (_propertyDescriptor.IsReadOnly || ParentGrid.ReadOnly) { //access = "readonly"; access = "disabled"; } //// Try to get a DisplayName for this property //var displayNameAttribute = // _propertyDescriptor.Attributes.OfType<DisplayNameAttribute>().Select(att=>att.DisplayName).FirstOrDefault(); //if (!string.IsNullOrWhiteSpace(displayNameAttribute)) // displayedName = displayNameAttribute; // Detect any supplied mappings for this Property Name and honor its settings. var propertyMapped = false; foreach (PropertyMap propertyMap in ParentGrid.PropertyMaps) { if ((Name != propertyMap.PropertyName) || (!propertyMap.Enabled)) { continue; } // If a PropertyMap exists and there is no URL provided, however a DisplayedName // is provided...the intent is to simply rename the actual PropertyName to // the optionally provided DisplayName. This provides developers a mechanism for // replacing machine readable PropertyNames with human suitable DisplayNames. displayedName = (String.IsNullOrEmpty(propertyMap.DisplayedName)) ? Name : propertyMap.DisplayedName; if (String.IsNullOrEmpty(propertyMap.Url)) { break; } propertyMapped = true; var url = ParentGrid.DeTokenizePropertyMap(propertyMap.Url); propertyUrl = String.Format(@"<a class=""PropertyGridPropertyLink"" href=""{0}"" title=""{1}"">{2}</a>", url, propertyMap.ToolTip, propertyMap.LinkDescription); break; } writer.WriteLine( //@"<td class=""PropertyName"" valign=""top"" align=""left"" width=""100%"">{0}</td>", @"<span class=""PropertyName"">{0}", displayedName); writer.WriteLine(@"<span class=""PropertyDefinition""><br/>{0}</span>", Definition); writer.WriteLine(@"</span>"); //writer.Write(@"<td class=""PropertyValue"" valign=""top"" align=""left"" width=""100%"">"); writer.WriteLine(@"<span class=""PropertyValue"">"); if (!String.IsNullOrEmpty(propertyUrl)) { writer.Write(propertyUrl); } if (!propertyMapped) { var typeConverter = _propertyDescriptor.Converter; if (typeConverter.GetStandardValuesSupported()) { writer.Write(@"<select id=""{0}"" name=""{0}"" {1} >", ControlId, access); foreach (var standardValue in typeConverter.GetStandardValues()) { var val = typeConverter.ConvertToString(standardValue); writer.Write( val == ValueString ? @"<option selected=""selected"">{0}</option>" : @"<option>{0}</option>", val); } writer.Write("</select>"); } else { if (typeConverter is StringArrayConverter) { writer.Write(@"<textarea id=""{0}"" name=""{0}"" rows=""5"" value=""{1}"" class=""PropertyValue"" {2}></textarea>", ControlId, ValueString, access); } else if (typeConverter.CanConvertFrom(typeof(string))) { writer.Write(@"<input id=""{0}"" name=""{0}"" type=""Text"" value=""{1}"" class=""PropertyValue"" {2} />", ControlId, ValueString, access); } else { writer.Write(@"<div class=""PropertyNestedGrid"">"); // ------------ // WIP: This needs some work. Does not handle collections...yet. // Also, it would be nice to put this in a collapsed div with // a plus/minus toggler. var nestedEditor = new ObjectWebEditor { ID = ID + "X", HiddenCategories = ParentGrid.HiddenCategories, HiddenProperties = ParentGrid.HiddenProperties, ShowCategoryLabels = ParentGrid.ShowCategoryLabels, HideReadOnly = ParentGrid.HideReadOnly, SelectedObject = Value, Page = Page }; nestedEditor.Render(writer); writer.Write(@"</div>"); // ------------ } } } //writer.Write(@"</td>"); //writer.Write(@"</tr>"); //writer.Write(@"</table>"); writer.Write(@"</span><br />"); }