I have reviewed several answers that all seem to indicate that using the format of [textboxID].Text should allow me to reference the input data when I am in the code behind, but this does not hold true for me. My example is as follows:
/** .aspx markup file **/
'''
<asp:ListView ID="ListViewWorkTypes" runat="server" InsertItemPosition="LastItem" >
<LayoutTemplate>
<table id="TypeRecords" runat="server" >
<tr id="TR1" runat="server" >
<td id="Td1" runat="server" >
<table runat="server" id="TypePlaceholder" >
<tr id="Tr2" runat="server" >
<td id="Td10" hidden="hidden" runat="server">Task Name</td>
<td id="Td20" runat="server">PhaseId</td>
<td id="Td30" runat="server">DeptId</td>
<td id="Td11" runat="server">Initial Value</td>
<td id="Td21" runat="server">Order</td>
<td id="Td23" runat="server">Math Operator</td>
<td id="Td31" runat="server">Option Value 1</td>
<td id="Td41" runat="server">Option Value 2</td>
<td id="Td51" runat="server">Option Value 3</td>
<td id="Td61" runat="server">Option Value 4</td>
<td id="Td71" runat="server">Option Value 5</td>
</tr>
<tr runat="server" id="itemPlaceholder">
</tr>
<tr runat="server">
<td runat="server" colspan="2">
<asp:DataPager ID="DataPager1" runat="server">
<Fields>
<asp:NextPreviousPagerField ButtonType="Link" />
<asp:NumericPagerField />
<asp:NextPreviousPagerField ButtonType="Link" />
</Fields>
</asp:DataPager>
</td>
</tr>
</table>
</td>
</tr>
</table>
</LayoutTemplate>
<InsertItemTemplate>
<tr id="NewWorkTaskRow">
<td id="NewTaskName">
<asp:Label runat="server" ID="TaskNameLabel" Visible="true" AssociatedControlID="TaskNameTextBox" Text="Task Name"/>
<asp:TextBox ID="TaskNameTextBox" runat="server" Visible="true" Text='<%# Bind("Name") %>' /><br />
</td>
<td id="NewPhase">
<asp:Label runat="server" ID="PhaseLabel" Text="Phase" AssociatedControlID="PhaseDropDown"/>
<asp:DropDownList ID="PhaseDropDown" runat="server" DataSourceID="SqlDataPhase" DataTextField="PhaseName" DataValueField="PhaseID" AppendDataBoundItems="true" >
<asp:ListItem Text="Choose Phase" Value="" Selected="False"></asp:ListItem>
</asp:DropDownList>
</td>
<td id="NewFunctionalArea">
<asp:Label runat="server" ID="DeptLabel" Text="Fuctional Area" AssociatedControlID="DeptDropDown" />
<asp:DropDownList ID="DeptDropDown" runat="server" DataSourceID="SqlDataDept" DataTextField="Dept" DataValueField="DeptId" AppendDataBoundItems="True">
<asp:ListItem Text="Choose Functional Area" Value="" Selected="True"></asp:ListItem>
</asp:DropDownList>
</td>
<td>
<asp:Label runat="server" ID="BaseValueLabel" AssociatedControlID="BaseValueTextBox" Text="Base Value" />
<asp:TextBox ID="BaseValueTextBox" runat="server" Text='<%# Bind("BaseValue") %>' /><br />
</td>
<td>
<asp:Label runat="server" ID="OrderLabel" AssociatedControlID="OrderTextBox" Text="Order" />
<asp:TextBox ID="OrderTextBox" runat="server" Text='<%# Bind("ordr") %>' /><br />
</td>
<td>
<asp:Label runat="server" ID="MathOperatorLabel" AssociatedControlID="MathOperatorTextBox" Text="Math Operator" />
<asp:TextBox ID="MathOperatorTextBox" runat="server" Text='<%# Bind("MathOperator") %>' /><br />
</td>
<td>
<asp:Label runat="server" ID="Opt1Label" AssociatedControlID="Opt1TextBox" Text="Option Value" />
<asp:TextBox ID="Opt1TextBox" runat="server" Text='<%# Bind("Opt1") %>' /><br />
</td>
<td>
<asp:Label runat="server" ID="Opt2Label" AssociatedControlID="Opt2TextBox" Text="Option Value" />
<asp:TextBox ID="Opt2TextBox" runat="server" Text='<%# Bind("Opt2") %>' /><br />
</td>
<td>
<asp:Label runat="server" ID="Opt3Label" AssociatedControlID="Opt3TextBox" Text="Option Value" />
<asp:TextBox ID="Opt3TextBox" runat="server" Text='<%# Bind("Opt3") %>' /><br />
</td>
<td>
<asp:Label runat="server" ID="Opt4Label" AssociatedControlID="Opt4TextBox" Text="Option Value" />
<asp:TextBox ID="Opt4TextBox" runat="server" Text='<%# Bind("Opt4") %>' /><br />
</td>
<td>
<asp:Label runat="server" ID="Opt5Label" AssociatedControlID="Opt5TextBox" Text="Option Value" />
<asp:TextBox ID="Opt5TextBox" runat="server" Text='<%# Bind("Opt5") %>' />
</td>
<td>
<asp:LinkButton ID="InsertButton" runat="server" OnClick="InsertType" Text="Insert" ></asp:LinkButton>
</td>
</tr>
</InsertItemTemplate>
'''
/** Code Behind **/
'''
protected void InsertType(object sender, EventArgs e)
{
string Name = "";
int BaseValue = 0;
bool LOE;
int ordr;
char operation;
int Opt1 = 0;
int Opt2 = 0;
int Opt3 = 0;
int Opt4 = 0;
int Opt5 = 0;
int TypeID = 0;
string strtypecon = WebConfigurationManager.ConnectionStrings["DefaultEstimateConnection"].ConnectionString;
SqlConnection typeconx = new SqlConnection(strtypecon);
SqlCommand TypeCmd = new SqlCommand()
{
Connection = typeconx
};
/*** Attempted with the aforementioned TextBox ID reference ***/
Name = TaskNameTextBox.Text;
/*** Err msg: TaskNameTextBox does not exist in current context ***/
/*** Attempted with Request form ***/
Name = Request.Form["TaskNameTextBox"];
/** Checkpoint at this point of the process indicates a null value for Name **/
ListViewWorkTypes.FindControl("TaskNameTextBox").ToString();
TypeCmd.Parameters.AddWithValue("#Name", Name);
'''
This did not seem different from the other code I had seen on this site that had reportedly worked.
Ok,a few things:
first, if you not using the grids built in edit or features, then I would dump all templates EXCEPT for the ItemTemplate. I find in most cases, I don't need all the additional templates, and I blow them out (delete them).
So, I will often drop in a lv, use the wizard to generate the data and layout. I then delete the datasource on the page and then collapse each edit/alternative/insert/edit templates and DELETE them. blow out (delete) the datasource control placed on your form, and you go from a galactic mess of huge markup into a simple nice clear easy to work with lv.
So, even in your case, it not clear if you actually using the insert template, or that you simply drop in a linkbutton and added a event to that link button.
(BTW: you can drop in a plane jane asp.net button - they often look MUCH nicer).
So, I don't know if you using the insert template, but you do have the button dropped into your insert template, but I don't know if its ALSO in the item template.
As noted:
You have (or might) have item/edit/alternating/insert templates. And given the screen might also have many rows? The when you reference a text box, then which one and which row and from which template would you get?
Answer: massive world wide confusing!!!
So, when using a gridview, listview, repeater, formview, details view?
They all work quite much the same - they are "repeaters" in the sense that the layout you have is used over and over. As a result, you of course cannot use ay:
TaskNameTextBox.Text
Now, as noted, it not at all clear if you actually using the inert template. and as noted, in most cases, I simple dump ALL the templates except for Item template. And in most cases it is less code, less markup, less things to maintain.
Ok, however lets address the linkbutton click event and code.
There are actually about 5 approaches here. and picking which approach to get the row you trying to work on will DEPEND VERY much on what you trying to do.
Probably the most easy way to get this to work?
You can add to the button a CommandName tag. This tag has specials names that can cause the iistview events to fire. However, looking at your listview, it don't look like you have ANY of the wired up.
So, you could use CommandName="select"
This will then cause the row command to fire (but row index has NOT changed yet!!! - it will. However, RowCommand event does pass the row.
but, right after above, the SelectedIndex of the listview will fire and MORE important the index DOES change.
However, there also another way to get the current row, and save you to having to learn the COMPLEX event model of the listview.
What you can do is simply pick up and get the current row you clicked on (the insert link button you have). When we get that row you can THEN pluck out values from that row.
However, to get such values, we can't an odn't use the control names. What you do get is a "object"/thing that represents the one row, and from that you can use FindConrol to pull out the value.
As noted, there would be a gallziooon instances of that control, and even different templates- so becomes impossible as to what control you trying to get.
So, for these "repeater" types of controls, you can't reference thee control directly anymore. you ALWAYS have to get the row instance, and THEN from that row instance pluck out/get/grab the control by use of FindControl.
So, the first part, the hard part and the VALUABLE part is to get that row you clicked on.
As noted, you could have/let/allow the row index changed event fire, and from that event you can then get the current row though ListView2.xxxxxx.
Howevver, from that simple button drop into the itemtemplate? (and again I STONG recommend you only have the itemtempate if you not using the lv features to edit (such as insert template).
So, in the button click event, we can get that all knowing and all valuable row. We just need that row thing, and from that we are home free.
it works like this:
protected void cmdLstSel_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
ListViewDataItem gRow = (ListViewDataItem)btn.Parent.Parent.Parent;
// ListViewDataItem gRow = (ListViewDataItem)GetParentObj(btn.Parent, typeof(ListViewDataItem));
int hID = (int)ListView1.DataKeys[gRow.DisplayIndex]["ID"];
note carful the use of Datakeys. You REALLY but REALLY want to set this if you need and want the PK row ID from the database. This also has the HUGE benefit of you not having to include the database PK id in the lv markup. (this also can be huge in terms of security issues - you don't have to include or expose the database PK id in the markup and thus it is NEVER exposed client side - do keep this in mind).
Ok, so the above gets the current row (ListViewDataItem) by using the parent property of that control clicked on. (.parent = "<td">, and we go up one more, and then one more again. So, note how I used .Parent.Parent.Parent. I even wrote a routine to do this for me, since often due to a extra div or whatever, you might have to .parent up a few more to get that row.
And of course in your case, we would do/use this:
LinkButton btn = (LinkButton)sender);
ListViewDataItem gRow = (ListViewDataItem)btn.Parent.Parent.Parent;
// ListViewDataItem gRow = (ListViewDataItem)GetParentObj(btn.Parent, typeof(ListViewDataItem));
int hID = (int)ListView1.DataKeys[gRow.DisplayIndex]["ID"];
But, ONCE we have that gRow, then you can get the value of the given text box like this:
TextBox MyTaskNameTextBox;
MyTaskNameTextBox = (TextBox)gRow.FindControl("TaskNameTextbox");
// text of box now is MyTaskNameTextBox.Text
As noted, sometimes you have to "guess" how many parents to go up to get that all valued "row". I often guess, compile and run, and the error message actually tells me you can't cast that "td" to ListViewitem, so I put in another one and compile again. But, I even became tired of that, so I wrote this routine to get the row for me:
public Control GetParentObj(Control c, Type T)
{
if (c.Parent.GetType() == T)
return c.Parent;
else
// keep looking
return GetParentObj(c.Parent, T);
}
Note above in my sample code, I commented out the use of above, but you can give this routine a try if you missing or guessing as to how many parents you have to bubble up to get the row is hit and miss for you.
As noted, you could also not use this .parent approach, and use the built in listview events, but, I often as noted, DUMP the huge mess of extra templates, and dump the HUGE complex event model of the lv, and just code my way right though this issue (to get that one all valuable row).
Noob question.
Why does this not work into my .aspx file?
<body>
<asp:Label ID="Label1" runat="server" Text='<%=System.DateTime.Today.Day.ToString()%>' ></asp:Label>
</body>
It does display the <%=System.DateTime.Today.Day.ToString()%> string which is obviously not what I want.
Same result if I try to display the content of a code behind variable:
<asp:Label ID="label" runat="server" Text='<%= versionNumber %>' >
versionNumber being properly instanced and set into the code behind.
You cannot mix server controls with code blocks.
There are two ways to work around that limitation:
Just use <%=System.DateTime.Today.Day.ToString()%> without a Label around it
Use codebehind to set Label1.Text = System.DateTime.Today.Day.ToString();
The first way will display the date to the user, but you cannot further change it from codebehind.
The second way does enable you to alter the text from codebehind.
It is true you can't mix server controls with Code blocks,
If its compulsory for you to use Server side control, and you don't even want to set value from code behind then you can go for this solution.
<asp:Label ID="Label1" runat="server"><%=System.DateTime.Today.Day.ToString() %></asp:Label>
Similarly you can use code behind variable as follows ,
<asp:Label ID="Label1" runat="server"><%=versionNumber %></asp:Label>
If you really want to use a asp:Label
Use it as follows:
<asp:Label ID="Label1" runat="server"><%=System.DateTime.Today.Day.ToString() %></asp:Label>
Is it possible to programatically insert C# Inline Expressions as the values for ASP.NET Controls in your server-side code?
I'm currently using a DataList to display a lot of data in a table. I want to be able to dynamically change the columns of that table, so I need to be able to edit what controls are in its ItemTemplate.
However, in addition to editing the controls in the ItemTemplate, I need to be able to alter the value that is binded to each control in the template, because I want to dynamically change what is being displayed.
So what I currently have is a static table that doesn't change:
<asp:DataList ID="dataList" runat="server" OnSelectedIndexChanged="dataList_OnSelectedIndexChanged" DataSourceID="peopleData">
<ItemTemplate>
<table>
<tr>
<td>
<asp:LinkButton ID="NameLink" OnClientClick="onPageUpdate()" CommandName="Select" Text='<%# Eval(this.Name) %>' ForeColor='<%# Eval("this.NameColor") %>' runat=Server" />
</td>
<td>
<asp:Label Text='<%# Eval("this.Values[\"Age\"]") %>' ForeColor='<%# Eval("this.ValueColors[\"Age\"]") %>' runat="Server">
</td>
// OTHER COLUMNS WITH DIFFERENT DATA
</tr>
</table>
</ItemTemplate>
</asp:DataList>
// OBJECT DATA SOURCE CODE
I know how to dynamically add Controls to the ASPX web page. However, I don't know how to add the inline expressions.
I've tried doing the following but it doesn't work because of the type mismatches:
Label label = new Label();
label.Text = "<%# Eval(\"this.Values[\\\"Age\\\"]\") %>";
label.ForeColor = "<%# Eval(\"this.ValueColors[\\\"Age\\\"]\") %>";
Is there a way of achieving this or doing something similar?
My only other option that I can think of right now is to scrap using the DataList and ItemTemplate and just generate each row myself.. That's a lot more coding versus just using the ItemTemplate.
Not sure if this would help you, but look at http://msdn.microsoft.com/en-us/library/system.web.ui.databinder(v=vs.100).aspx
It is showing using of the hand-written exposure of properties. If your property were always call "magic" and you return the appropriate value for magic within your code would that get you what you need?
I have the following DataList-
<td>
<asp:Label ID="Label3" runat="server" Text="Exclude"></asp:Label>
<asp:DataList runat="server" ID="excludeTextBox">
<ItemTemplate>
<br />
<asp:TextBox ID="myTextBox" runat="server" Text='<%# Container.DataItem.ToString() %>'></asp:TextBox>
</ItemTemplate>
</asp:DataList>
<td>
<asp:Label ID="Label4" runat="server" Text="Active"></asp:Label>
<asp:DataList runat="server" ID="activeCheck" >
<ItemTemplate>
<br />
<asp:CheckBox ID="CheckBox1" runat="server" Checked='<%# Container.DataItem.ToString().Equals("1") %>' OnCheckedChanged="CheckBox1_CheckedChanged" AutoPostBack="true" />
</ItemTemplate>
</asp:DataList>
</td>
So this is generating a textBox and checkBox for every row that exits in the database.
Currently there is no save action associated with the dataList, however if a user checks or unchecks one of the checkBoxes this calls a webservice and toggles the value in a data base table.
My question is, after a user has edited the text in some of the textBoxes and checked or unchecked some of the check boxes, how can I catch the changes in a save changes button. Because if the items have been dynamically created then technically they do not exist on the page. I want to do this without having a save option on ever row on the dataList.
protected void saveChanges_Click(object sender, EventArgs e)
{
// capture all edits and call update webservice method.
}
You'd essentially have to build the representation of the changes. Because there is no generic solution to this, I don't have any code, but here is the process:
As an item changes, you have to store what changed. You could store the indexes of the rows that actually changed in a hidden variable on the page, or store the changes in a JavaScript object. When save changes is clicked, on the client you then loop through these changes, and if they exist send them in bulk or one at a time.
If you had a hidden field with a value like 0,2,5 for each index that changed, you could easily find those items, grab the values from the form, and ship them off to the web service. Or, you could build a JavaScript object that has the changes like:
{ key: 2, checked: true, text:"My new text" }
Store these in an array, and push them up to the server through the web service.
I have the following textBox -
<asp:TextBox ID="TextBox1" runat="server" AutoPostBack="true"></asp:TextBox>
<asp:AutoCompleteExtender ID="AutoCompleteExtender1" runat="server"
MinimumPrefixLength="1" ServiceMethod="PRETURN" ServicePath="WebService1.asmx"
TargetControlID="TextBox1"> </asp:AutoCompleteExtender>
When a user types into TextBox1 this sends a request to WebService1.asmx and calls the PRETURN service method. So as a user is typing the textBox brings a drop down list of strings that start with the letters the user is typing.
I now have the following DataList -
<asp:DataList runat="server" ID="pTextBox" >
<ItemTemplate>
<asp:CheckBox ID="CheckBoxPN" runat="server" Checked='false' OnCheckedChanged="CheckBoxPN_CheckedChanged" AutoPostBack="true" />
<asp:TextBox ID="profileTextBox" runat="server" Text='<%# Container.DataItem.ToString() %>'></asp:TextBox>
</ItemTemplate>
</asp:DataList>
Where on Page_Load -
WebService1 ws = new WebService1();
pTextBox.DataSource = ws.Method();
pTextBox.DataBind();
My problem is I want to combine the functionality of the textBox with the DataList. So that when a user types into the textBox, instead of the textBox having a dropdown list, the rows in the DataList are updated. So for instance, if Text in the profileTextBox did not contain the prefix text in TextBox1 when the user was typing, it would disappear. Leaving the user with a list of rows relevant to their search. How can I achieve this?
Others have done something similar to the GridView control, using JQuery to show/hide rows depending on the filter criteria. One solution, which should be easily adaptable to the DataList, is available here.