My page looks correct in Firefox and IE8. But in IE7, a nested gridview spills into the adjacent cell, much like the issue here.
Looking at it in the developer tools, there is an inline-style associated with the table that ASP.NET generated, and it has a width attribute of 100%. If I remove this, the nested table pops back where it belongs.
Problem is, nowhere is an inline-style set. In fact, if I try to set width='250px', it gets overridden with width='100%'. If I try to remove the width attribute in the code-behind, attrGridView.Attributes["Width"] is null, and calling .Remove() does nothing. But every asp.net-generated gridview-table has an inline style with width='100%' set on it (it's only causing me issues in one place).
Setting table-layout='fixed', as suggested in the article I linked to, did not help.
How do I get ASP.NET to stop setting this property?
Some code:
<asp:TemplateField HeaderText="Attributes" SortExpression="Attributes">
<HeaderStyle CssClass="GridHeaderCell" />
<ItemStyle CssClass="GridTableCell AttrGridCellPadding" />
<ItemTemplate>
<asp:GridView id="attributesGridView" runat="server"
AutoGenerateColumns="false" ShowHeader="false" GridLines="None"
AlternatingRowStyle-BackColor="White" CssClass="StupidGridView" >
<EmptyDataTemplate>
<p class="italic">There are no attributes for this request.</p>
</EmptyDataTemplate>
<Columns>
<asp:TemplateField>
<ItemStyle CssClass="AttrTableCell" />
<ItemTemplate>
<asp:Label id="attributeName" runat="server"
Text='<%# Eval("Name") + ": "+ Eval("Value") %>'
CssClass="AttrGridCell"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ItemTemplate>
</asp:TemplateField>
.StupidGridView {
width: 250px;
}
Themes are being applied and overriding control-level settings. Check theme settings on page, web.config, or anywhere else a theme may be set.
Unfortunately, the ASP.NET html rendering is really bad.
Microsoft know that and provided Control adapters in 2006 which allow you to modify control rendering.
Instead of searching on how to override what ASP.NET render, I would advise to use CSSFriendly which provides control adapters for most ASP.NET bad-rendered controls.
If you don't need "pure-css rendering" and CSS afraid you, you can check how they do to create your own adapter.
ScottGu post on this subject from google.
Related
I have a Gridview and the columns defined like below.
When I run the program I get the error
Literal content is not allowed within a System.Web.UI.WebControls.DataControlFieldCollection
<Columns>
<asp:CommandField ButtonType="Image"
ControlStyle-Height="20"
ControlStyle-Width="30"
SelectImageUrl="tar.png"
SelectText="Select"
ShowSelectButton="true"/>
<asp:TemplateField HeaderText="Target Date">
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server"
Text='<%# Bind("tar_date") %>'>
</asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lbl1" runat="server"
Text='<%# Bind("tar_date") %>'>
</asp:Label>
</ItemTemplate>
<ItemStyle HorizontalAlign="Right" />
</asp:TemplateField>
</Columns>
Can anyone help me solving this?
Nothing seems to be wrong with your markup.
The only thing I would recommend is ending the Label control immediately and trying it again.
<asp:Label ID="lbl1" runat="server" Text='<%# Bind("tar_date") %>' />
// OR
<asp:Label ID="lbl1" runat="server" Text='<%# Bind("tar_date") %>'></asp:Label>
In the past I have seen issues when Tab, or some unintentional characters come in between some of the templated controls. Check if you have any such characters by redoing every line from scratch.
This question is a little old, but for the others who encounter this problem:
This problem can caused by not putting white space between properties. For example:
<asp:TextBox ID="TextBox1" runat="server"Text='<%# Bind("tar_date") %>'> </asp:TextBox> //wrong (no space before Text)
This was such a frustrating error to run into. I wasted about 4 hours on this and there are surprisingly few resources I could find on Google to help me troubleshoot it. I was updating a legacy application, so the intricacies of a GridView were a bit hazy since I haven't created one from scratch in a while.
At the end of it, the fix was a result of a suggestion by Raja to rewrite the control. Visual Studio wasn't highlighting a very important issue and the ambiguous nature of the error message had me looking at the wrong grid columns. Despite the error pointing to an issue with the TemplateField, the issue for me was actually in a BoundField.
During a conversion from Telerik RadGrid to GridView, the BoundField control had an orphaned <ItemStyle> tag nested inside of it, but the BoundField control doesn't allow this.
Visually, you wouldn't know or even suspect this, unless you have recent familiarity with GridView. You couldn't run into it by debugging. Visual Studio and the compiler were not reporting this either. So troubleshooting it was a beast.
The thing that worked was rewriting the grid, line-by-line. Thanks, Raja!
The autocomplete feature in Visual Studio wouldn't let me close the BoundField control to add any other tag/control of any kind. This is when I finally realized where the issue was.
I hope this helps another unlucky Googler. :)
I have a datagrid that needs one of the fields to hyperlink to a document housed on another server. The path is in this format: \\server\location\file.doc, but when I click on the cell in the data grid it becomes: http://myASPServer/Subfolder/server/location.file.doc. Is there any way that I can force this to go to the correct location? I know that you can prevent this for external websites by adding ftp:// or http://, but this does not seem to work for opening up this server location. Any suggestions?
I believe your answer can be found here on the asp.net forums http://forums.asp.net/t/1140909.aspx/1 - accepted answer from there below for your convenience.
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:HyperLink Text="TextField" id="myHL" runat="server"
NavigateUrl='<%# "file:///" + DataBinder.Eval(Container.DataItem, "Path").ToString() %>'></asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
</Columns>
I believe you need to prefix your links with file:/// for it would be file:///\\server\location\file.doc
I am creating a web interface which currently reads data in from an XML data file, parses it into an array of Objects, after which I bind it to the data source of a Gridview. I then use and to retrieve the data I want from the objects for each column.
However, I am at the point that I would like to have multiple tabs in this gridview, possibly controlled by different link buttons. Each tab would show a different set of columns.
What would be the best way to implement this? Do I need to have three separate GridViews in my page, and just show the one for which the user selected (based on the click to the link button), while hiding all the others? This seemed like it might be unnecessarily slow. Is it possible to do via one GridView?
Right now the entire GridView is contained in an AJAX update panel, with the code below:
<asp:Panel id="searchResultsGrid" runat="server" CssClass="searchResultsGrid">
<asp:GridView id="gridViewSearchResults" runat="server" AutoGenerateColumns="false"
AllowPaging="True" AllowSorting="True"
PageSize="25" Width="920" PagerSettings-Visible="false">
<Columns>
<asp:templatefield headertext="Test Column 1 Tab 1" HeaderStyle-HorizontalAlign="Left">
<itemtemplate>
<%# GetColumnInfo() %>
</itemtemplate>
</asp:templatefield>
<asp:templatefield headertext="Test Column 2 Tab 1" HeaderStyle-HorizontalAlign="Left">
<itemtemplate>
<%# GetColumnInfo() %>
</itemtemplate>
</asp:templatefield>
<asp:templatefield headertext="Test Column 3 Tab 1" HeaderStyle-HorizontalAlign="Left">
<itemtemplate>
<%# GetColumnInfo() %>
</itemtemplate>
</asp:templatefield>
<asp:templatefield headertext="Test Column 4 Tab 1" HeaderStyle-HorizontalAlign="Right" ItemStyle-HorizontalAlign="Right">
<itemtemplate>
<%# GetColumnInfo() %>
</itemtemplate>
</asp:templatefield>
<asp:templatefield headertext="Test Column 5 Tab 1" HeaderStyle-HorizontalAlign="Right" ItemStyle-HorizontalAlign="Right">
<itemtemplate>
<%# GetColumnInfo() %>
</itemtemplate>
</asp:templatefield>
<asp:templatefield headertext="Test Column 6 Tab 1" HeaderStyle-HorizontalAlign="Right" ItemStyle-HorizontalAlign="Right">
<itemtemplate>
<%# GetColumnInfo() %>
</itemtemplate>
</asp:templatefield>
<asp:templatefield headertext="Test Column 7 Tab 1" HeaderStyle-HorizontalAlign="Right" ItemStyle-HorizontalAlign="Right">
<itemtemplate>
<%# GetColumnInfo() %>
</itemtemplate>
</asp:templatefield>
</Columns>
<RowStyle CssClass="searchResultEntry borderTopGrey" />
<EmptyDataTemplate>
<p class="searchResultsEmpty">
<asp:Label ID="lblSearchResultsEmpty" runat="server" Text="No records matched the selected criteria. Please revise your criteria and try again." CssClass="searchResultsEmpty"></asp:Label>
</p>
</EmptyDataTemplate>
</asp:GridView>
</asp:Panel>
This is the code I currently have for one gridview, with the content of one tab. Based on jdk's response, how would I go about adding other TemplateFields for the second and third tabs, and then switching between displaying the different sets when a tab link button is clicked?
Thanks!
The page ViewState string can become very (unnecessarily) large when multiple GridViews are present (view its resulting HTML source code and search for "__VIEWSTATE" to see it). You can use one GridView control, like you said, and swap appropriate data into it depending on which LinkButton (a.k.a. "tab") was recently clicked.
If this is also a paginated data scenario, you can store a simple array of three integers in ViewState representing the current page number of each of the three sets of data, so you can display the most recent page of data when swapping them in and out of the one DataGrid control.
However if bandwidth is not a concern (i.e. if the page doesn't receive a lot of hits or runs on an Intranet) then don't worry as much about optimizing it.
I've done similar things before. I used template columns for the GridView. And put a Ajax control toolkit tab control in the GridView.
I would probably create a Custom Composite Control (as the tabbed-container) and add the grid-view to that. I would not bundle it into one.
Ok, this should be really easy, but I just don't have enough experience.
I need to throw a GridView on a WebForm and populate with a List, where Template is my class that has ID, Name, CreatedOn, etc... properties.
The GridView needs to display each Template Name as a link. The link should point to TemplateEdit.aspx page, with the following URL: TemplateEdit.aspx?ID={ID of Template}.
I also need a Delete link (preferably an image link), that should popup a Yes/No delete confirmation dialog.
I've actually done this before in 2005 or so, but I simply can't remember anymore.
Here's how you do it (borrowed the code from here to save some typing)
<asp:TemplateField HeaderText="Statement" SortExpression="Statement">
<ItemTemplate>
<asp:HyperLink ID="Link1" runat="server" NavigateUrl='<%# Bind("ID", "~/TemplateEdit.aspx?ID={0}") %>' Text="The Best Link"></asp:HyperLink >
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:ImageButton ID="DeleteButton" Runat="server" ImageUrl="~/images/delete.gif" OnClientClick="return confirm('Are you sure you want to delete this?');" ToolTip="Delete" CommandName="Delete" />
</ItemTemplate>
</asp:TemplateField>
didn't actually test it, but looks like it should work.
...I want to Show the 'delete' button when user is an admin, and show the 'add item' button when user is a contributor:
<!-- More code above -->
<asp:BoundField DataField="Description" HeaderText="Description" SortExpression="Description" />
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:LinkButton CSSClass="TableRightLink" ID="LinkButton1" runat="server" CausesValidation="False" CommandName="Delete"
Visible=<%# User.IsInRole(#"DOMAIN\CMDB_ADMIN") %>
Text="Delete"
OnClientClick="return confirm('Are you certain you want to delete this item?');"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<SelectedRowStyle VerticalAlign="Top" />
<HeaderStyle ForeColor="White" CssClass="TableHeader" BackColor="SteelBlue" />
</asp:GridView>
<asp:table width="100%" runat="server" CSSclass="PromptTable" Visible=<%# User.IsInRole(#"DOMAIN\CMDB_CONTRIBUTE") %> >
<asp:tablerow><asp:tablecell HorizontalAlign=Center>
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="AddConfigItem.aspx" ForeColor="LightCyan">Add Item</asp:HyperLink>
</asp:tablecell></asp:tablerow></asp:table>
The Delete button 'visible' attribute works fine. But, the "add item' hyperlink doesn't. It always shows.
View-source tells me that %# User.IsInRole(#"DOMAIN\CMDB_CONTRIBUTE") %> isn't evaluating to anything. Any idea why this is?
Try setting it in code behind, instead of in mark up, in Page_Load. Assuming the id is promptTable (it wasn't given in your example), just add:
promptTable.Visible = User.IsInRole(#"DOMAIN\CMDB_CONTRIBUTE");
Presumably this needs to be done regardless of whether it is a postback or not.
FWIW, #Keltex is right about the control not being databound so <%# %> won't work. Unfortunately, the <%= %> syntax won't either because it always returns a string and you need a boolean value there. I couldn't find any other syntax that would work in this case. You could probably do this by turing off display using javascript, but I suspect that you don't want the table to be rendered to the page if not in the correct group (as opposed to just being hidden or removed from the DOM once on the client). Doing it in the code behind, I think is the right way to go about it.
Try:
Visible='<%= User.IsInRole(#"DOMAIN\CMDB_CONTRIBUTE") %>'
The asp:table doesn't appear to be databound.