gaillimhabu Registered User
#1

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!!!

gaillimhabu Registered User
#2

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?

mewso Moderator
#3

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.

gaillimhabu Registered User
#4

gaillimhabu Registered User
#5

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

Evil Phil Contact Section
#6

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

Spunj Registered User
#7

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.

mewso Moderator
#8

gaillimhabu

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?

gaillimhabu Registered User
#9

gaillimhabu Registered User
#10

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>";
    }

Evil Phil Contact Section
#11


        ...
        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

gaillimhabu Registered User
#12

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.

Evil Phil Contact Section
#13

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

mewso Moderator
#14

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.

tvp1125 Registered User
#15

Want to share your thoughts?

Login here to discuss!