0

I need to reference the label value from lblCaseStatus on the selected row of the following gridview:

<asp:GridView ID="grdTaskList" runat="server" DataKeyNames="CaseID"
              AutoGenerateColumns="False" AllowSorting="True" AllowPaging="True"
              PageSize="20">
    <Columns>
        <asp:BoundField DataField="Task" HeaderText="Task" SortExpression="Task" 
                        ItemStyle-Width="350px" />
        <asp:BoundField DataField="DueDate" HeaderText="Due Date" SortExpression="DueDate"
                        DataFormatString="{0:d}" />
        <asp:TemplateField HeaderText="Case Status">
            <ItemTemplate>
                <asp:Label ID="lblCaseStatus" runat="server"></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField>
            <ItemTemplate>
                <asp:LinkButton ID="btnView" runat="server" Text="View"
                                CommandName="ViewIntake"
                                CommandArgument='<%# Eval("CaseID") %>' 
                                Font-Bold="true" />
            </ItemTemplate>
            <ItemStyle HorizontalAlign="Center" />
    </asp:TemplateField>
    </Columns>
</asp:GridView>  

I have searched the web and I have not found any solutions that will work. I tried using one based on this SO answer (https://stackoverflow.com/a/10784039/3938754) which included this disclaimer:
Remark: this only works with Boundfields.
I am using a TemplateField and guessing this is why it fails on the line:

Dim id as Guid = grdTaskList.DataKeys(row.RowIndex).Value

with the error reading:
Specified cast is not valid. (When casting from a number, the value must be a number less than infinity.)
Both the RowIndex and Value have data.

Private Sub grdTaskList_RowCommand(sender As Object, e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles grdTaskList.RowCommand
    If (e.CommandName = "ViewIntake") Then
        Dim caseID As Integer = Int32.Parse(e.CommandArgument.ToString())

        Dim row As GridViewRow = CType(CType(e.CommandSource, Control).NamingContainer, GridViewRow)
        Dim id As Guid = grdTaskList.DataKeys(row.RowIndex).Value
        Dim caseStatus As String = CType(row.Cells(2), DataControlFieldCell).Text

        Response.Redirect(IntakeSite.EditIntake.GetPageURL(caseID:=caseID, caseStatus:=caseStatus))
    End If
End Sub

So how do I reference the label value inside an ItemTemplate from the RowCommand method?

Thanks in advance for your time and assistance.

1 Answers1

0

This assignment will trigger InvalidCastException because it tries to convert Object value directly from DataKey.Value property to Guid type:

Dim id As Guid = grdTaskList.DataKeys(row.RowIndex).Value 'throws InvalidCastException

You need to use CType or System.Guid constructor instead:

' using type conversion
Dim id As Guid = CType(grdTaskList.DataKeys(row.RowIndex).Value, System.Guid)

' alternative with Guid constructor
Dim id As Guid = New Guid(DirectCast(grdTaskList.DataKeys(row.RowIndex).Value, String))

Also Guid.Parse method can be used to ensure that passed value is in proper GUID format:

Dim id As Guid = Guid.Parse(grdTaskList.DataKeys(row.RowIndex).Value.ToString())

Or if the GUID uses certain formatting like hyphens and/or enclosed with braces, use Guid.ParseExact with format specifier as in example below:

'example format: 00000000-0000-0000-0000-000000000000
Dim id As Guid = Guid.ParseExact(grdTaskList.DataKeys(row.RowIndex).Value.ToString(), "D")

As a side note, use TryParse or TryParseExact if you want to put conditions regarding valid GUID value.

Update 1:

Since DataKey.Value has Integer type, CType argument needs slightly modified:

Dim id As Guid = New Guid(CType(grdTaskList.DataKeys(row.RowIndex).Value, Integer))

Or use Integer to Guid conversion with custom shared function:

' other module
Public Shared Function ToGuid(ByVal value As Integer) As Guid
   Dim bytes As Byte() = New Byte(16)
   BitConverter.GetBytes(value).CopyTo(bytes, 0)
   Return New Guid(bytes)
End Function

' RowCommand method
Dim val As Integer = CType(grdTaskList.DataKeys(row.RowIndex).Value, Integer)
Dim id As Guid = ToGuid(val)
Tetsuya Yamamoto
  • 24,297
  • 8
  • 39
  • 61
  • All four Guid suggestions failed: 1) Specified cast is not valid; 2) Unable to cast object of type 'System.Int32' to type 'System.String'; 3) Guid should contain 32 digits with four dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx); 4) Unrecognized Guid format. – Michael Callas May 02 '18 at 13:03
  • I have read up on **Guid** and not sure how it pertains to referencing the label value in an ItemTemplate as the **id** variable is _not_ used. What I need to know is, "how do I reference the label value inside an ItemTemplate from the RowCommand method." – Michael Callas May 02 '18 at 13:11
  • The way you're referencing the value looks right, but the passed value sounds not fit into specified GUID format (there's why you should use `ParseExact` or `TryParseExact` with specified format). Can you tell us which kind of value exactly returned by `DataKey.Value` property? – Tetsuya Yamamoto May 02 '18 at 15:31
  • If I understand your question correctly, the DataKey.Value property is of type Int32. – Michael Callas May 02 '18 at 16:01
  • If you intended to convert `Integer` value from `DataKey` to `Guid`, you need to convert it using `Guid` constructor or create shared function to do so (see updated section). – Tetsuya Yamamoto May 03 '18 at 04:24