Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie
Hi there,
There is an issue with role permissions that is being worked on at the moment.
If you are having trouble with access or permissions on regional forums please post here to get access: https://www.boards.ie/discussion/2058365403/you-do-not-have-permission-for-that#latest

Dynamically Changing a Hyperlinkfield in a GridView - - .NET 2.0 + C#

  • 31-05-2007 11:43am
    #1
    Registered Users, Registered Users 2 Posts: 546 ✭✭✭


    Hi,

    I have a hyperlink field in my grid view and I need to dynamically change which page it opens up depending on the value of a certain field called IsLocked.

    So if IsLocked is true, I go to the url "requestsaccess.aspx?cmpid=12345" and
    if IsLocked is false, I got to the url "view.aspx?cmpid=12345"

    My example currently only takes care of when IsLocked is false:
    <asp:HyperLinkField HeaderText="Company Name" DataTextField="cmpName" 
         SortExpression="cmpName" DataNavigateUrlFields="cmpID" 
         DataNavigateUrlFormatString="view.aspx?cmpid={0}" 
    />
    
    

    How can I change this to include both cases?

    I think I need to change the hyperlink field to a template field but don't know what to do after that?

    Any pointers please!!!


Comments

  • Registered Users, Registered Users 2 Posts: 546 ✭✭✭gaillimhabu


    I've just changed the hyperlink field to a template field.
    <asp:TemplateField HeaderText="Company Name" InsertVisible="False" 
                       SortExpression="cmpName">
        <ItemTemplate>
             <asp:HyperLink ID="CompanyName" runat="server" 
                       NavigateUrl='<%# Eval("cmpID", "view.aspx?cmpid={0}") %>'
                       Text='<%# Eval("cmpName") %>'>
             </asp:HyperLink>
        </ItemTemplate>
    </asp:TemplateField>
    
    

    Any idea how to incorporate the second url if the IsLocked field is true?


  • Moderators, Science, Health & Environment Moderators Posts: 9,035 Mod ✭✭✭✭mewso


    Well you need to override the rowdatabound event of the gridview and get a reference to the hyperlink:-

    dim hyp as hyperlink = ctype(e.row.cells(0).findcontrol("CompanyName"), hyperlink)

    I'm a vb.net man so you'll have to convert this yourself but the one thing here is you need to reference the cell that is the template field. i.e. if it's the third field in the datagrid then it should be e.rows.cell(2) for example.

    Now the best way to check your IsLocked parameter is put it into the datakeys collection of the gridview:-

    <gridview id="blah" datakeynames="id,islocked"...

    for example.

    Now in the same event as above grab the islocked value for this record:-

    dim islocked as boolean = CType(gridview.DataKeys(e.Row.RowIndex)(1), boolean)

    Again the (1) is because I have islocked as the second datakey.

    Now I can set the navigateurl of the hyperlink based on this:-

    if islocked then
    hyp.navigateurl = "etc."
    else

    etc.

    Sorry about the vb but I think you might be able to sort it yourself from this.


  • Registered Users, Registered Users 2 Posts: 546 ✭✭✭gaillimhabu


    Thanks Musician. I think I'm getting there with the info you supplied.

    company.aspx:
    <asp:GridView ID="CompaniesGridView" datakeynames="cmpID,IsLocked"    
            runat="server" AutoGenerateColumns="False"
            OnRowDataBound="CompaniesGridView_RowDataBound">
      <Columns>
         <asp:TemplateField HeaderText="Company Name" InsertVisible="False" 
                SortExpression="cmpName">
           <ItemTemplate>
              <asp:HyperLink ID="CompanyName" runat="server" 
                   NavigateUrl='<%# Eval("cmpID", "view.aspx?cmpid={0}") %>'
                   Text='<%# Eval("cmpName") %>'>
              </asp:HyperLink>
           </ItemTemplate>
         </asp:TemplateField>
      </Columns>
    </asp:GridView>
    
    

    Company.aspx.cs
    protected void CompaniesGridView_RowDataBound(object sender, 
                                                          GridViewRowEventArgs e)
    {
        HyperLink hyp = (HyperLink)(e.Row.Cells[0].FindControl("CompanyName"));
    
        bool IsLocked = System.Convert.ToBoolean(CompaniesGridView.DataKeys[e.Row.RowIndex][1]);
            
        if (IsLocked)
        {
           hyp.NavigateUrl = "requestsaccess.aspx?cmpid="+
                                CompaniesGridView.DataKeys[e.Row.RowIndex][0];
        }
        else
        {
           hyp.NavigateUrl = "view.aspx?cmpid="+
                                CompaniesGridView.DataKeys[e.Row.RowIndex][0];
         }
    }
    
    

    Currently getting the error "Index was out of range. Must be non-negative and less than the size of the collection." for the line
    bool IsLocked = System.Convert.ToBoolean(CompaniesGridView.DataKeys[e.Row.RowIndex][1]);


  • Registered Users, Registered Users 2 Posts: 546 ✭✭✭gaillimhabu


    Can anyone spot what I'm doing wrong in the line
    bool IsLocked = System.Convert.ToBoolean(CompaniesGridView.DataKeys[e.Row.RowIndex][1]);

    for me to get the 'Index out of range error'

    I believe 1 is correct for the RowIndex as IsLocked is my 2nd datakey.

    Even changing that RowIndex number results in the same error anyhow


  • Registered Users, Registered Users 2 Posts: 7,468 ✭✭✭Evil Phil


    Would you not put a breakpoint on that line and examine it when it executes?


  • Advertisement
  • Registered Users, Registered Users 2 Posts: 437 ✭✭Spunj


    You could always write an anchor manually, thats what I usually do in this kind of case.
    <ItemTemplate>
    <a class="whatever" href='<%#Convert.ToInt32(Eval("IsLocked"))== 1 ? "requestsaccess.aspx" : "view.aspx"%>?cmpid=<%# Eval("cmpID")%>'> <%# Eval("cmpName")%></a>
    </ItemTemplate>
    

    Something like that. Bear in mind thats off the top of my head so there may be a syntax error, but it seems to look ok.


  • Moderators, Science, Health & Environment Moderators Posts: 9,035 Mod ✭✭✭✭mewso


    Currently getting the error "Index was out of range. Must be non-negative and less than the size of the collection." for the line
    bool IsLocked = System.Convert.ToBoolean(CompaniesGridView.DataKeys[e.Row.RowIndex][1]);

    Well to start with the obvious. Is the islocked field in your select statement?


  • Registered Users, Registered Users 2 Posts: 546 ✭✭✭gaillimhabu


    Thanks Guys for all your answers.

    Musician:
    I decided against your first option in the end as didn't have time to debug it as had to get the code finished today. I'll prob get back to it again when I get some free time

    Spunj:
    Your option works fine:
    
    <ItemTemplate>
    <a href='<%#Convert.ToInt32(Eval("IsLocked"))== 1 ? 
    "requestsaccess.aspx" : "view.aspx"%>?cmpid=<%# Eval("cmpID")%>'> 
    <%# Eval("cmpName")%></a>
    </ItemTemplate>
    
    

    In case anyone is interested:
    I figured out another option which is handy if you want to return a hyperlink for one case and maybe a string for the other. Could do that Spunj's
    way as well but the syntax would be slighty different.
    
    <ItemTemplate>
      <%# FormatCompany(DataBinder.Eval(Container.DataItem, "IsLocked"), 
    DataBinder.Eval(Container.DataItem, "cmpID"), 
    DataBinder.Eval(Container.DataItem, "cmpName"))%>
    </ItemTemplate>
    
    and in code behind
    
    protected string FormatCompany(object IsLocked, object cmpID, object cmpName)
        {
            if (IsLocked == DBNull.Value || IsLocked.Equals(true) || 
              cmpID == DBNull.Value || cmpName == DBNull.Value)
            {
                return "Restricted";  
            }
            return "<a href=view.aspx?cmpid="+cmpID.ToString()+">"+cmpName.ToString()+"</a>";
        }
    


  • Registered Users, Registered Users 2 Posts: 546 ✭✭✭gaillimhabu


    Following on from this topic...I want to add a Tooltip if the hyperlink which points to the view.aspx page is returned. Have tried a few ways but having no luck.

    Any ideas?

    Current Code:

    company.aspx
    
    <ItemTemplate>
      <%# FormatCompany(DataBinder.Eval(Container.DataItem, "IsLocked"), 
    DataBinder.Eval(Container.DataItem, "cmpID"), 
    DataBinder.Eval(Container.DataItem, "cmpName"))%>
    </ItemTemplate>
    

    company.aspx.cs
    
    protected string FormatCompany(object IsLocked, object cmpID, object cmpName)
        {
            if (IsLocked == DBNull.Value || IsLocked.Equals(true) || 
              cmpID == DBNull.Value || cmpName == DBNull.Value)
            {
                return "Restricted";  
            }
            return "<a href=view.aspx?cmpid="+cmpID.ToString()+">"+cmpName.ToString()+"</a>";
        }
    
    


  • Registered Users, Registered Users 2 Posts: 7,468 ✭✭✭Evil Phil


            ...
            return "<a href=view.aspx?cmpid="+cmpID.ToString()+" [COLOR="Blue"]TITLE='tooltiptext'[/COLOR]>"+cmpName.ToString()+"</a>";
        }
    
    

    Should do that for you.

    I personally don't like to return HTML from my code behind as I don't think its a good programming practice but it looks like that would require quite a rewrite on your behalf. But this is the kind of thing that can be done in the markup, its just something to think about for the future :)


  • Advertisement
  • Registered Users, Registered Users 2 Posts: 546 ✭✭✭gaillimhabu


    Thanks Evil Phil. Worked like a dream

    You are right. It's probably not best practice to have some of my html in my code behind. Just with the option I took in the end it was hard to avoid.

    Will certainly consider it for future coding.


  • Registered Users, Registered Users 2 Posts: 7,468 ✭✭✭Evil Phil


    Yeah, if it ain't broken - don't fix it.


  • Moderators, Science, Health & Environment Moderators Posts: 9,035 Mod ✭✭✭✭mewso


    I know you were rushed but overriding the itemdatabound method is to me the best of doing these things.
    Anyway at the very least make sure you are returning title in lower case for the good of all web standards geeks like myself.


  • Closed Accounts Posts: 1 tvp1125


    Hi,

    I have a hyperlink field in my grid view and I need to dynamically change which page it opens up depending on the value of a certain field called IsLocked.

    So if IsLocked is true, I go to the url "requestsaccess.aspx?cmpid=12345" and
    if IsLocked is false, I got to the url "view.aspx?cmpid=12345"

    My example currently only takes care of when IsLocked is false:
    ...

    I know this was posted a while ago, but while we were reading this thread, we discovered that the DataNavigateUrlFields property is an Array.

    We had an issues of if a specific type then use a specific page, also if type=4 then use P_id, else use O_id.

    We added a couple CASE statements to query to add columns to the dataset.

    the added SQL was:
    [SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] casestmnt [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]String[/COLOR][/SIZE][SIZE=2] = [/SIZE][SIZE=2][COLOR=#800000]", (CASE Type WHEN 1 THEN 'Page_1' WHEN 2 THEN 'Page_2' WHEN 4 THEN 'Page_4' WHEN 5 THEN 'Page_5' ELSE 'Unknown' "[/COLOR][/SIZE][SIZE=2] & _[/SIZE]
    [SIZE=2][COLOR=#800000]" END) AS GoToPage, (CASE Type WHEN 4 THEN 'p_id' ELSE 'o_id' END) AS UseThisField "[/COLOR][/SIZE]
    


    The hyperlinkfield looked like this:
    [SIZE=2][COLOR=#0000ff]<[/COLOR][/SIZE][SIZE=2][COLOR=#800000]asp[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]:[/COLOR][/SIZE][SIZE=2][COLOR=#800000]HyperLinkField[/COLOR][/SIZE][SIZE=2][COLOR=#ff0000]DataNavigateUrlFields[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]="ID,GoToPage,UseThisField"[/COLOR][/SIZE][SIZE=2][COLOR=#ff0000]DataNavigateUrlFormatString[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]="{1}.aspx?{2}={0}"[/COLOR][/SIZE]
    [SIZE=2][COLOR=#ff0000]HeaderText[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]="Action"[/COLOR][/SIZE][SIZE=2][COLOR=#ff0000]Text[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]="View">[/COLOR][/SIZE]
    [SIZE=2][COLOR=#0000ff]<[/COLOR][/SIZE][SIZE=2][COLOR=#800000]ItemStyle[/COLOR][/SIZE][SIZE=2][COLOR=#ff0000]HorizontalAlign[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]="Center"[/COLOR][/SIZE][SIZE=2][COLOR=#ff0000]VerticalAlign[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]="Middle"[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]/>[/COLOR][/SIZE]
    [SIZE=2][COLOR=#0000ff]</[/COLOR][/SIZE][SIZE=2][COLOR=#800000]asp[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]:[/COLOR][/SIZE][SIZE=2][COLOR=#800000]HyperLinkField[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]>[/COLOR][/SIZE]
    

    I refreshed the data souce and hid the two columns that I added.

    Hope this helps....knowing the DataNavigateUrlFields is an Array is a big help..:)


Advertisement