gailhl
asked on
Get the value from a cell in a detailsview row without knowing the index
Hi Experts,
I need to do something like this:
If personDetails.Rows(16).Cel ls(0).Text = "some text" Then ...
But rather than referring to rows(16), I'd like to be able to refer to Rows("columnName").
This should be easy but I can't find it! Is there a way of doing this?
Thanks!
Gail HL
I need to do something like this:
If personDetails.Rows(16).Cel
But rather than referring to rows(16), I'd like to be able to refer to Rows("columnName").
This should be easy but I can't find it! Is there a way of doing this?
Thanks!
Gail HL
ASKER
Thanks for your reply, Gavin ...
I don't think I am mixing up columns and rows, just sloppy in wording the question.
The above example I gave works - the problem with it is that it means any time a new field is added to the DetailsView, I've got to remember to change the code to reflect the new position of "rows(16)". So I'd rather refer to it by some sort of key name, and as so much else in .NET is based on dictionaries, I'm guessing that the detailsview control might have keys somewhere that I can access, if only I knew the syntax.
Thanks,
Gail HL
I don't think I am mixing up columns and rows, just sloppy in wording the question.
The above example I gave works - the problem with it is that it means any time a new field is added to the DetailsView, I've got to remember to change the code to reflect the new position of "rows(16)". So I'd rather refer to it by some sort of key name, and as so much else in .NET is based on dictionaries, I'm guessing that the detailsview control might have keys somewhere that I can access, if only I knew the syntax.
Thanks,
Gail HL
I just did a quick test on my machine and to me Rows is the collection of DataRows in the details view.
So if I have 10 records returned I get 10 rows. It doesn't care about me changing the amount of fields returned only that amount or records.
I still say you cannot give the rows object a name instead of an index.
So if I have 10 records returned I get 10 rows. It doesn't care about me changing the amount of fields returned only that amount or records.
I still say you cannot give the rows object a name instead of an index.
ASKER
Sorry, I still think we aren't talking about the same thing.
I'm talking about the new DetailsView control in ASP.Net 2.0, Visual Studio 2005.
There is only one row in a detailsview. Its "rows" (as referred to in original question) are actually the "columns" of the underlying "table" (or dataview). In other words, the rows and columns are inverted in the detailsview control.
Therefore, rows(16) refers to the value in the 15th column (0 based) for the one record which is bound to the detailsview. Whenever I add a new column to the stored procedure that is the source of the data, the number of items in the rows collection will change.
So if I want to base a condition on the value in that field for that single record, I have to use the syntax
If personDetails.Rows(16).Cel ls(0).Text = "some text" Then ...
But that's dodgy because at some future point, if the underlying procedure is changed, that field could be in rows(17) rows(23) -- in the detailsview control, that is (not in the underlying table).
But being a bit of a newbie to ASP.NET and to Visual Studio 2005, I don't actually know how to query the value in the cell any other way (I don't know the syntax for querying the underlying data before the detailsview control inverts it).
But I'm guessing that there probably IS a better way than what I am doing.
Thanks
Gail HL
I'm talking about the new DetailsView control in ASP.Net 2.0, Visual Studio 2005.
There is only one row in a detailsview. Its "rows" (as referred to in original question) are actually the "columns" of the underlying "table" (or dataview). In other words, the rows and columns are inverted in the detailsview control.
Therefore, rows(16) refers to the value in the 15th column (0 based) for the one record which is bound to the detailsview. Whenever I add a new column to the stored procedure that is the source of the data, the number of items in the rows collection will change.
So if I want to base a condition on the value in that field for that single record, I have to use the syntax
If personDetails.Rows(16).Cel
But that's dodgy because at some future point, if the underlying procedure is changed, that field could be in rows(17) rows(23) -- in the detailsview control, that is (not in the underlying table).
But being a bit of a newbie to ASP.NET and to Visual Studio 2005, I don't actually know how to query the value in the cell any other way (I don't know the syntax for querying the underlying data before the detailsview control inverts it).
But I'm guessing that there probably IS a better way than what I am doing.
Thanks
Gail HL
Okay lets just ignore the row section :)
You are worried that the SQL will change which will then stop you code from working?
Easiest way to avoid this, which I would always recommend you do, is to be specific about what you want to display. For example
<asp:DetailsView DataSourceID="DetailsSourc e" AutoGenerateRows="false" Runat="Server">
<Fields>
<asp:BoundField DataField="LastName" HeaderText="Last Name:" />
<asp:BoundField DataField="FirstName" HeaderText="First Name:" />
<asp:BoundField DataField="Extension" HeaderText="Extension:" />
</Fields>
</asp:DetailsView>
Now image the DataSource "DetailsSource" return 10 fields in it's SQL and you only want to show 3. Just specify the 3 exact fields you want. So when someone updates the stored proc to return 12 fields your grid is still the same as when you develope it. (Unless someone changes the proc and no longer returns the required fields.)
In regard to your second question, to query the data before it is bound you can put your code in the DetailsView.OnItemDataBoun d event. Then you can easily loop through the recorsd there and do what you like.
The Row object does not have a dictionary so in reply to your original question
[But rather than referring to rows(16), I'd like to be able to refer to Rows("columnName")]
You can't.
Hope I have cleared up everything here :), if not just yell and we can sort it out.
You are worried that the SQL will change which will then stop you code from working?
Easiest way to avoid this, which I would always recommend you do, is to be specific about what you want to display. For example
<asp:DetailsView DataSourceID="DetailsSourc
<Fields>
<asp:BoundField DataField="LastName" HeaderText="Last Name:" />
<asp:BoundField DataField="FirstName" HeaderText="First Name:" />
<asp:BoundField DataField="Extension" HeaderText="Extension:" />
</Fields>
</asp:DetailsView>
Now image the DataSource "DetailsSource" return 10 fields in it's SQL and you only want to show 3. Just specify the 3 exact fields you want. So when someone updates the stored proc to return 12 fields your grid is still the same as when you develope it. (Unless someone changes the proc and no longer returns the required fields.)
In regard to your second question, to query the data before it is bound you can put your code in the DetailsView.OnItemDataBoun
The Row object does not have a dictionary so in reply to your original question
[But rather than referring to rows(16), I'd like to be able to refer to Rows("columnName")]
You can't.
Hope I have cleared up everything here :), if not just yell and we can sort it out.
ASKER
Well...perhaps I'm completely losing my mind. Or totally unobservant. But as far as I can tell, there is no OnItemDataBound event in the DetailsView control.
Are we both talking about Visual Studio 2005 and VB?
Thanks
Gail
PS What I am trying to do is color-code the text displayed in a cell depending on the data value. The orginal example I posted works but this is a project being built and the procs are not final. The client is still adding and removing fields etc. so the position changes, and I've already had to change the code twice.
Are we both talking about Visual Studio 2005 and VB?
Thanks
Gail
PS What I am trying to do is color-code the text displayed in a cell depending on the data value. The orginal example I posted works but this is a project being built and the procs are not final. The client is still adding and removing fields etc. so the position changes, and I've already had to change the code twice.
Take a look here....
http://www.thescripts.com/forum/thread424945.html
It is the DataBound event and not ItemDataBound
Basically
void DetailsView1_DataBound(obj ect sender, EventArgs e)
{
if(((DetailsView)sender).C urrentMode == DetailsViewMode.Edit)
{
DropDownList ddl=(DropDownList)((Detail sView)send er).FindCo ntro l("DropDownList1");
if (ddl1 !=null) //you found the dropdownlist
{
//execute statements to add the desired data to it
}
}
}
This example is in C# and for aa DropDown but it should get you going
This is what the online C# --> VB.Net generator gave me. It is normally accurate but sometimes get's it wrong
Private Sub DetailsView1_DataBound(ByV al sender As Object, ByVal e As EventArgs)
If (CType(sender,DetailsView) .CurrentMo de = DetailsViewMode.Edit) Then
Dim ddl As DropDownList = CType(CType(sender,Details View).Find Contro,Dro pDownList)
l("DropDownList1")
If (Not (ddl1) Is Nothing) Then
'execute statements to add the desired data to it
End If
End If
End Sub
http://carlosag.net/Tools/CodeTranslator/Default.aspx
http://www.thescripts.com/forum/thread424945.html
It is the DataBound event and not ItemDataBound
Basically
void DetailsView1_DataBound(obj
{
if(((DetailsView)sender).C
{
DropDownList ddl=(DropDownList)((Detail
if (ddl1 !=null) //you found the dropdownlist
{
//execute statements to add the desired data to it
}
}
}
This example is in C# and for aa DropDown but it should get you going
This is what the online C# --> VB.Net generator gave me. It is normally accurate but sometimes get's it wrong
Private Sub DetailsView1_DataBound(ByV
If (CType(sender,DetailsView)
Dim ddl As DropDownList = CType(CType(sender,Details
l("DropDownList1")
If (Not (ddl1) Is Nothing) Then
'execute statements to add the desired data to it
End If
End If
End Sub
http://carlosag.net/Tools/CodeTranslator/Default.aspx
Okay I posted an attempted answer to two different questions here :)...
Please ignore the DetailsViewMode.Edit part because that does not apply to you, you can cast your label using the findcontrol option and then change it as you like (Change DropDown to label)
Other than that it should work with no problems.
Please ignore the DetailsViewMode.Edit part because that does not apply to you, you can cast your label using the findcontrol option and then change it as you like (Change DropDown to label)
Other than that it should work with no problems.
ASKER
Sorry, it just doesn't work. The field I'm trying to access in the condition isn't a template field; it's an asp:checkbox which is databound.
This works - but I don't like the reference by index.
Dim lblPN As Label = Me.personDetails.FindContr ol("lblPer sonNotes")
If Not (lblPN Is Nothing) Then
Dim ckb As CheckBox = Me.personDetails.Rows(16). Cells(1).C ontrols(0)
If ckb.Checked = True Then
lblPN.ForeColor = Drawing.Color.Red
Else
lblPN.ForeColor = Drawing.Color.Black
End If
End If
Perhaps FindControl would work if I change it to a template field -- but I still find it impossible to believe that there is no straightforward way to address the value of an asp databound control without referring to it by index or converting it to a template field.
Thanks
GHL
This works - but I don't like the reference by index.
Dim lblPN As Label = Me.personDetails.FindContr
If Not (lblPN Is Nothing) Then
Dim ckb As CheckBox = Me.personDetails.Rows(16).
If ckb.Checked = True Then
lblPN.ForeColor = Drawing.Color.Red
Else
lblPN.ForeColor = Drawing.Color.Black
End If
End If
Perhaps FindControl would work if I change it to a template field -- but I still find it impossible to believe that there is no straightforward way to address the value of an asp databound control without referring to it by index or converting it to a template field.
Thanks
GHL
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Since all rows are the same you cannot give it a name.
I think you are getting confused between columns and rows.
Rows are vertical and columns horizontal.