Add support for fields to databound controls - asp.net

For example when using a gridview. When you specify the columns
BoundField for example won't work if you are binding it to a field instead of a property.
I guess this is so because when the gridview is looking for the DataField property it looks for a property and not a field. Now the question is how can i change this behavior to make it possible to use fields. I know i have to inherit from the gridview, but i don't know where to go from there.

This functionality is so wrapped into the framework and wasn't designed for extensibility so no you can't change this behavior; the only thing you can do is to create wrapper objects or wrap fields with properties.
Or render the UI in your own way, which then you lose the GridView in-built functionality.

Wrap the fields with Properties
private string fieldA;
public string FieldA
{
get { return fieldA; }
set { fieldA = value; }
}

Related

Find input control in dynamically added div

Upon dynamically adding a Table webcontrol from the code-behind of my aspx page, I then use
TableCell tableCell = tableRow.Cells[1];
foreach (Control ctrc in tableCell.Controls)
{
...
}
to find the objects I am interest in.
I would rather use a div with a span tag, instead of the table, and use something similar to
foreach (Control ctrc in span.Controls)
{
...
}
As my div also has a label, how do I specify that I am only interested in the objects contained within the span tag?
You can use LINQ to filter the list by a type:
span.Controls.OfType<TextBox>();
I know TextBox controls are not what you are looking for, but I'm not sure what specifically you need, so replace TextBox with whatever... (HtmlGenericControl?). You can also use LINQ Where, which is nice:
span.Controls.Where(i => [SOME CONDITION]);
And the list is filtered to whatever you want. Since you are using HTML elements with runat="server", you have to know what the HTML control type is, which I am not 100% sure what the class names are since I don't use them that often.

asp.net 4.0: is there any equivalent of ClientIDMode for the names of INPUTs?

I have an asp:ListView whose ClientIDMode is set to Predictable. Its ItemTemplate contains an asp:textbox.
The ID of the textbox is acting as I expect it to, but its name is still using what looks like an AutoID-style algorithm:
<input name="lvFields$ctrl0$tbVal" id="lvFields_tbVal_somekey" type="text"/>
Is there a way for me to cause the name of the input to act like the ID does?
(Edit in response to questions below:)
The Name of the input element is what's in the POST data, so if a postback alters the list to which the ListView is bound (for example, exchanging two elements) the values from the textboxes end up associated with the wrong keys, because the framework is correlating them based on the Name and not the ID.
You can change the name of an Input by using the method from the following post but modifying it slightly:
how to remove 'name' attribute from server controls?
I over-rode the RenderChildren method on a Page control as I just wanted full control of the HTML for a few controls:
protected override void RenderChildren(HtmlTextWriter writer)
{
var unScrewNamesRender = new RenderBasicNameHtmlTextWriter(writer);
base.RenderChildren(unScrewNamesRender);
}
private class RenderBasicNameHtmlTextWriter : HtmlTextWriter
{
public RenderBasicNameHtmlTextWriter(TextWriter writer) : base(writer) { }
public override void AddAttribute(HtmlTextWriterAttribute key, string value)
{
if (key == HtmlTextWriterAttribute.Name && value.Contains("POLine"))
{
value = value.Substring(value.LastIndexOf("$") + 1);
}
base.AddAttribute(key, value);
}
}
You do need to know what you're doing if you attempt this, WebForms will think the control is missing so you can't use it in any postbacks. For my purposes, where I wanted to add an arbitrary number of multiple lines either server or client-side without having to deal with .Net Ajax controls, it works fine.
I'm pretty sure you can't change the name, especially when you modify the ClientIDMode. As an alternative, you can add a Title attribute. VS will flag this as unknown in the server side code, but it renders correctly in the HTML. If you're doing some client-side manipulation, you can address the input as such:
<script type="text/javascript">
$(document).ready(function () {
$('input:text[title="TextBoxName"]').datepicker();
});
</script>
As far as I know, there is no way to change the name of the input element. The name corresponds to the UniqueID property, which is generated by the system, and which you have no control over. Seems you have to find a way to achieve what yo want using only the control ID.
Both names are using the predictable pattern; originally, name also equaled ct100_ct100 etc. From what I see, that's a predictable name. Client ID value will always use _ between control prefixes and Unique ID (name attrib) will always use $. The two will always match, except for a few controls that leverage name for something (radiobuttonlist uses for grouping).
HTH.
I had the exact same problem once and had to use one of these properties exposed in "System.Web.UI.Control" to get clientside control name in server side.
Play around with these properties and construct the "Name" in server side yourself and use Request.Form("NameHere")
Me.ClientIDSeparator
Me.IdSeparator
Me.UniqueID
A jquery solution
function removeNameAttribute() {
$('input, select').each(function () {
$(this).removeAttr("name");
});
}
//Use a HtmlGenericControl
HtmlGenericControl input = new HtmlGenericControl("input");``
input.ID = "lvFields_tbVal_somekey";
input.Attributes.Add("name", "tbVal");
input.Attributes.Add("type", "text");
input.ClientIDMode = ClientIDMode.Static;

Flex extending ComboBox

I created a class CustomCombo.as that extends ComboBox. What is happening is that the CustomCombo combobox is showing as being editable. I do not want this and I cant find the properties to set the editable to false.
I also tried setting the combobox's textInput.editable control to false, but to no avail.
Any help would be greatly appreciated.
CustomCombo.as
package custom {
import spark.components.ComboBox;
public class CustomCombo extends ComboBox {
public function CustomCombo() {
super();
// this.editable = false; //<-- THIS DOESNT WORK ***Access of possibly undefined property editable through a reference with static type custom:CustomCombo
// this.textInput.editable = false; //<-- THIS DOESNT WORK ***Cannot access a property or method of a null object reference
}
}
}
After rummaging through the Flex 4 API I found that they suggest to use the DropDownList control. From what I can see is that they removed the editable property from the ComboBox control in Flex 4, but I may be wrong.
I implemented DropDownList and that solved my problem.
I see that you're using spark and not mx. The editable property I referred to is applicable only to mx based list. In spark, ComboBox extends DropDownListBase and is editable by default.
The ComboBox control is a child class of the DropDownListBase control. Like the DropDownListBase control, when the user selects an item from the drop-down list in the ComboBox control, the data item appears in the prompt area of the control.
One difference between the controls is that the prompt area of the ComboBox control is implemented by using the TextInput control, instead of the Label control for the DropDownList control. Therefore, a user can edit the prompt area of the control to enter a value that is not one of the predefined options.
For example, the DropDownList control only lets the user select from a list of predefined items in the control. The ComboBox control lets the user either select a predefined item, or enter a new item into the prompt area. Your application can recognize that a new item has been entered and, optionally, add it to the list of items in the control.
The ComboBox control also searches the item list as the user enters characters into the prompt area. As the user enters characters, the drop-down area of the control opens. It then and scrolls to and highlights the closest match in the item list.
So ideally, you should be using DropDownList in this case.
You're getting null error when trying to access textInput from the constructor because it hasn't been created yet. In mx based controls (Flex-3), you can access it from the creationComplete handler; I'm not quite sure how to do it for spark based controls.
Update: I think I've figured out how to access skin parts in spark (though you might wanna use the DropDownBox instead). You have to override the partAdded method.
override protected function partAdded(partName:String, instance:Object):void
{
super.partAdded(partName, instance);
if (instance == textInput)
{
textInput.editable = false;
}
}
There's one catch though: it may not work in this case. The source code of ComboBox.as says that
the API ignores the visual editable and selectable properties
So DropDownList it is!
Initial answer, posted for mx ComboBox.
This shouldn't happen as the default value of the editable property is false.
Try explicitly setting the value to false from the constructor.
public function CustomCombo() {
super();
this.editable = false;
}

change id of a server control in asp.net

Hai guys,
I used find control to find a list item of an unoreder list inside a master page from content page using this,
Control home = this.Page.Master.FindControl("list").FindControl("home");
Now i have to change the id of the control home to "current" because to apply css for it....
Do you know the Type of the control you're finding? Neither Control nor ListItem expose a CssClass property, however, ListItem does expose it's Attributes property.
Update based on comment and other question:
You should be using System.Web.UI.HtmlControls.HtmlGenericControl
So something like this should work for you:
HtmlGenericControl home =
this.Page.Master.FindControl("list").FindControl("home")
as HtmlGenericControl;
string cssToApply = "active_navigation";
if (null != home) {
home.Attributes.Add("class", cssToApply);
}
If you think there might already be an class assigned to it that you need to append to you could do something like:
if (null != home) {
if (home.Attributes.ContainsKey("class")) {
if (!home.Attributes["class"].Contains(cssToApply)){
// If there's already a class attribute, and it doesn't already
// contain the class we want to add:
home.Attributes["class"] += " " + cssToApply;
}
}
else {
// Just add the new class
home.Attributes.Add("class", cssToApply);
}
}
If they aren't ListItems, cast them to the correct type, and modify the attributes collection as before, unless there's a CssClass property for that type.
Yes, to use css id's in asp.net is a big problem. first of all you can change your server control's id to what you want but, this will be regenerated by ASP.NET depending on the position of the control in your page's control tree.
My recommendation is to use cssclass property of the controls, and to replace the css ids to class.

How do I make a property of custom control to be a generic type?

I have created a custom ASP.NET control ( derived from WebControls.TextBox).
I want to add a property to that control which will be of a type.
This property will actually always be some type of enum .
So when in the designer I look at the properties window of that control - I want to be able to assign value to that property by a selection from the specific enum .
So I want to see there the list of enumerators from the enumeration that I pass as ..
Example ( not actuall code that will compile .. just to show what I mean):
I have 2 enums :
enum MyEnumABC
{
A,B,C
}
enum MyColor
{
Red,Blue,Green
}
I have this control:
public class MyTextBox<T> : TextBox
{
public T Classification
{
get { }
set { }
}
}
Now I create a webpage which have following controls:
<Alex:MyTextBox runat=server id="alex" Classification=MyEnumABC.A></Alex:MyTextBox>
<Alex:MyTextBox runat=server id="alex2" Classification=MyColor.Red></Alex:MyTextBox>
The question is where can I actually pass the type to the constructor of that control ?
( since the page class is the one who calls the constructors of the controls.)
Where I actually need to set the type of alex1 to be of MyEnumABC , and the type of alex2 of type MyColor.
And the second question is how I make the VS2008 to support this in the designer of HTML ( so that when I type the Classification in the tag - it will open the write enum for selection of the value) and the property page of the control.
I hope you understand what I mean here.
Thanks .
The designer will support enum properties without you having to do anything special. Just specify the property in your control's code, give it all the usual attributes to allow it to be displayed in the property window and the property window will automatically display the enum values in a dropdown.

Resources