Wednesday, March 21, 2012

DropDownExtender in a GridView issues (v1.0 beta)

I am trying to add a DropDownExtender within a GridView control using the code below but it fails i.e. The DropDownExtender is never displayed (no javascript errors). Then if I use the paging in the gridview to navigate to another page and hover over a row it causes a javascript error 'Line 196 Error: Object doesn't support this method or property'.

I've tried this with other controls (e.g. TextboxWatermark) in a GridView and they work ok but are a bit glitchy. Is this a known issue?

<asp:GridView ID="GridView1" runat="server" AllowPaging="True" AutoGenerateColumns="False"
DataKeyNames="Number,Sequence" DataSourceID="SqlDataSource1">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Panel ID="DropPanel" runat="server" CssClass="ContextMenuPanel" Style='display:none;visibility:hidden;'>
<asp:LinkButton runat="server" ID="Option1" Text="Option 1" CssClass="ContextMenuItem" OnClick="OnSelect" />
<asp:LinkButton runat="server" ID="Option2" Text="Option 2" CssClass="ContextMenuItem" OnClick="OnSelect" />
<asp:LinkButton runat="server" ID="Option3" Text="Option 3 (Click Me!)" CssClass="ContextMenuItem" OnClick="OnSelect" />
</asp:Panel>
<asp:Label ID="TheLabel" runat="server" Text="Howydoing" />
<ajaxToolkit:DropDownExtender ID="DDE" runat="server" DropDownControlID="DropPanel" TargetControlID="TheLabel"/>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Number" HeaderText="Number" ReadOnly="True" SortExpression="Number" />
<asp:BoundField DataField="Sequence" HeaderText="Sequence" ReadOnly="True" SortExpression="Sequence" />
<asp:BoundField DataField="Reference" HeaderText="Reference" SortExpression="Reference" />
<asp:BoundField DataField="Title" HeaderText="Title" SortExpression="Title" />
</Columns>
</asp:GridView>

Javascript where error occurs is: (this is part of the AjaxControlToolkit runtime scripts):

// NOTE: [rb] replaced with CommonToolkitScripts version
// var offsetParentLocation = Sys.UI.DomElement.getLocation(offsetParent);
// var parentBounds = Sys.UI.DomElement.getBounds(parent);
var offsetParentLocation = CommonToolkitScripts.getLocation(offsetParent);
var parentBounds = CommonToolkitScripts.getBounds(parent);

The problem here looks to be an issue with the current beta of ASP.NET AJAX, and I am following up with Shawn Burke and the ASP.NET AJAX team at Microsoft. The issue at hand is that ScriptManager currently emits all of its script for Extenders and ScriptReferences in it's own PreRender event which will happen before the PreRender event of the GridView. In the initial page request (Page.IsPostBack == false), a GridView bound using DataSourceID will delay binding until the last possible moment, which happens to be PreRender.

Until the ASP.NET AJAX team can address this issue, the quickest way to solve the bug is to temporarily add the following code to your Page or UserControl:

1protected void Page_Load(object sender, EventArgs e)2{3if (!Page.IsPostBack)4 {5 Grid.DataBind();6 }7}8 

Where Grid is the name of your DataGrid. This will cause the binding to the DataSourceID to happen in Load as opposed to PreRender.

Try the above and see if it solves your problem. I have another application I am working on that is exhibiting the same issue and this fixed it.


Thanks for that - that solved part of the problem to do with why it wasn't working on the first page display, however I was still getting the Javascript error. After a bit of debugging I found the following error in AjaxControlToolkit\Common\Common.js Line 196, which read:

var mediumThickness = this.parseBorderThickness("medium");

parseBorderThickness doesn't exist. however _borderThicknesses does and has values for thin, medium and thick. So changing the line to read:

var mediumThickness = this._borderThicknesses.medium;

solved the issue, however the DropDown is not quite aligned properly with the text so it looks like there is some additional work required in this area - maybe this will be fixed in the next release.


Thanks for pointing that out, that was a bad reference. The correct function name isparseBorderWidth not parseBorderThickness. I have made the change and checked it in and it should be corrected in the next toolkit release.

Can you provide me with some further details as to the alignment issue, or a sample I might be able to look at (source code/designwise) that I can try to use to figure out what might be causing a problem with the offset?


Source code is below. There are 2 issues:

1) The alignment of the DropDown box when hovering over 'TheLabel' is wrong in IE 6. This is correct when using Firefox 2.0. I am able to resolve this in IE by modifying the Common.js file like so:

if(defaultTdLeftBorderFound) offsetX -= mediumThickness + 4; //(Previously was -1)
if(defaultTdTopBorderFound) offsetY -= mediumThickness + 3; //(Previously was -1)

2) The glitchy behaviour I mentioned earlier seems to be a problem with other controls as well (at least TextBoxWatermark) which occurs when you navigate to the last page in a paged grid. I get a Javascript error in MicrosoftAjax.js: Line 451: Error: '_behaviors' is null or not an object

Default.aspx:
<%@. Page Language="C#" AutoEventWireup="true" %>
<%@. Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>
<script runat="server">
protected void Page_Load(Object sender, EventArgs args)
{
if (!Page.IsPostBack)
{
GridView1.DataBind();
}
}
</script>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
<style>
.ContextMenuPanel
{
background-color:white;
border: 1px solid #868686;
z-index: 1000;
cursor: default;
padding: 1px 1px 0px 1px;
font-size: 11px;
}
a.ContextMenuItem
{
display: block;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<div>
<asp:GridView ID="GridView1" runat="server" AllowPaging="True" AutoGenerateColumns="False"
DataKeyNames="Number,Sequence" DataSourceID="XmlDataSource2">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Panel ID="DropPanel" runat="server" CssClass="ContextMenuPanel" Style='display:none;visibility:hidden;'>
<asp:LinkButton runat="server" ID="Option1" Text="Option 1" CssClass="ContextMenuItem" />
<asp:LinkButton runat="server" ID="Option2" Text="Option 2" CssClass="ContextMenuItem" />
<asp:LinkButton runat="server" ID="Option3" Text="Option 3 (Click Me!)" CssClass="ContextMenuItem" />
</asp:Panel>
<asp:Label ID="TheLabel" runat="server" Text="Howydoing" />
<ajaxToolkit:DropDownExtender ID="DDE" runat="server" DropDownControlID="DropPanel" TargetControlID="TheLabel"/>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Number" HeaderText="Number" ReadOnly="True" SortExpression="Number" />
<asp:BoundField DataField="Sequence" HeaderText="Sequence" ReadOnly="True" SortExpression="Sequence" />
<asp:BoundField DataField="Reference" HeaderText="Reference" SortExpression="Reference" />
<asp:BoundField DataField="Title" HeaderText="Title" SortExpression="Title" />
</Columns>
</asp:GridView>
<asp:XmlDataSource ID="XmlDataSource2" runat="server">
<Data>
<TheData>
<row Number="asdfasdf" Sequence="001" Title="eflwef fwe " Reference="fwefwewefwef"/>
<row Number="asdfasdf" Sequence="002" Title="eflwef fwe " Reference="fwefwewefwef"/>
<row Number="asdfasdf" Sequence="003" Title="eflwef fwe " Reference="fwefwewefwef"/>
<row Number="asdfasdf" Sequence="004" Title="eflwef fwe " Reference="fwefwewefwef"/>
<row Number="asdfasdf" Sequence="005" Title="eflwef fwe " Reference="fwefwewefwef"/>
<row Number="asdfasdf" Sequence="006" Title="eflwef fwe " Reference="fwefwewefwef"/>
<row Number="asdfasdf" Sequence="007" Title="eflwef fwe " Reference="fwefwewefwef"/>
<row Number="asdfasdf" Sequence="008" Title="eflwef fwe " Reference="fwefwewefwef"/>
<row Number="asdfasdf" Sequence="009" Title="eflwef fwe " Reference="fwefwewefwef"/>
<row Number="asdfasdf" Sequence="010" Title="eflwef fwe " Reference="fwefwewefwef"/>
<row Number="asdfasdf" Sequence="011" Title="eflwef fwe " Reference="fwefwewefwef"/>
<row Number="asdfasdf" Sequence="012" Title="eflwef fwe " Reference="fwefwewefwef"/>
<row Number="asdfasdf" Sequence="013" Title="eflwef fwe " Reference="fwefwewefwef"/>
</TheData>
</Data>
</asp:XmlDataSource>
</div>
</form>
</body>
</html>

Notes: Web.config is taken direct from C:\Program Files\MicrosoftASP.NET\ASP.NET 2.0 AJAX Extensions\v1.0.61025\web_CTP.config and needsreferences to Microsoft.Web.Preview.dll and AjaxControlToolkit.dll


I've found that using a repeater table works just fine, but I continue to have problems with the GridView.

Suman Chakrabarti [MSFT]


I notive the alignment problem when placed inside a table with a border > 0px . If I set the boder to zero it lines up.
is this fixed in the current downloadable rc1 version?

Hi,

did you solve this problem? I have got the same problem at the moment. Is there a solution available?

--edit--

I just saw, my code is a little bit different

 <asp:HyperLink ID="hl1" runat="Server" NavigateUrl='<%# Eval("Id")%>' OnDataBinding="hl1_DataBinding"><asp:Label ID="TheLabel" runat="server" Text="Howydoing" /></asp:HyperLink>

No comments:

Post a Comment