Telerik RadGrid not showing any data in ASP.NET - asp.net

I'm trying to make a really simple grid for some data on an ASP.NET page, but clearly I'm doing something wrong here. First of all, let me show you the grid I have on my clientside:
<asp:Panel runat="server" ID="pnlDoorAccess" Visible="False">
<asp:UpdatePanel runat="server" ID="upnlDoorAccess" UpdateMode="Conditional" ChildrenAsTriggers="false">
<ContentTemplate>
<tel:RadGrid runat="server" ID="gvDoorAccess" AllowSorting="false" AllowPaging="false"
CssClass="col-sm-12 noPadding" MasterTableView-CssClass="table table-hover table-header-bg table-striped no-footer tableHeaderBorder"
OnNeedDataSource="radDoorAccess_NeedDataSource" OnItemDataBound="radDoorAccess_ItemDataBound">
<MasterTableView AutoGenerateColumns="false" TableLayout="Fixed" Caption="" FilterExpression="" AllowNaturalSort="false" DataKeyNames="Month" NoMasterRecordsText="No records to Display">
<Columns>
<tel:GridBoundColumn DataField="DoorName" HeaderText="Door Name" UniqueName="DoorName"></tel:GridBoundColumn>
</Columns>
</MasterTableView>
</tel:RadGrid>
</ContentTemplate>
</asp:UpdatePanel>
</asp:Panel>
So I wanna test the grid by only showing 1 column (DoorName), but so far it's not showing anything. Next is the server side code:
The DoorAccess property will fire up Controller.GetDoorAccess(CurrentUser.Id) when the Object Memorystore is empty and return me a DataTable object which I will return and eventually store into a DataSource property later on.
protected List<DoorAccess> DoorAccess
{
get
{
if (omsDoorAccess.DataItem == null || omsDoorAccess.DataItem.GetType() != typeof(List<Option>)) omsDoorAccess.DataItem = Controller.GetDoorAccess(CurrentUser.Id);
return (omsDoorAccess.DataItem as List<DoorAccess>);
}
set
{
omsDoorAccess.DataItem = value;
}
}
protected void Page_Load(Object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
LoadTab_DoorAccess();
}
}
private void LoadTab_DoorAccess()
{
// Future implementation
ReloadTab_DoorAccess();
}
private void ReloadTab_DoorAccess()
{
gvDoorAccess.DataBind();
upnlDoorAccess.DataBind();
upnlDoorAccess.Update();
}
protected void radDoorAccess_NeedDataSource(object sender, GridNeedDataSourceEventArgs e)
{
(sender as RadGrid).DataSource = DoorAccess;
// DoorAccess holds 128 items
}
protected void radDoorAccess_ItemDataBound(object sender, GridItemEventArgs e)
{
if (e.Item.ItemType != GridItemType.Item && e.Item.ItemType != GridItemType.AlternatingItem)
{
// Do stuff in the future
}
}
So what exactly is going on here? There is probably something obvious I'm missing, but right now I don't see it.
If this question makes no sense, could you show me a block of code that would help me create a simple grid?

I see that you have AutoGeneratedColumns="False", a single column declared with the DataField="DoorName", and DataKeyName="Month".
When using Advanced DataBinding the datasource you are binding to must match the schema in the RadGrid unless you are using AutoGenerateColumns.
Without seeing your controller code, I think the issue is with the above Markup. There is no way for the grid to bind the single column with the DataField of "DoorName" to the DoorAccess object using the DataKeyName of "Month"(not knowing where "Month" is coming from). Make sure the DataKeyName property contains a unique value from the DoorAccess object and that the column DataField is equal to any property in the DoorAccess object.
ASPX:
<telerik:RadGrid ID="RadGrid1" runat="server" OnNeedDataSource="RadGrid1_NeedDataSource">
<MasterTableView AutoGenerateColumns="False" DataKeyNames="Id" CommandItemDisplay="Top">
<Columns>
<telerik:GridBoundColumn DataField="Id" UniqueName="MyId" HeaderText="My Id"></telerik:GridBoundColumn>
<telerik:GridBoundColumn DataField="Value" UniqueName="Value" HeaderText="My Value"></telerik:GridBoundColumn>
</Columns>
</MasterTableView>
</telerik:RadGrid>
C#:
public class MyDataModel
{
public int Id { get; set; }
public string Value { get; set; }
}
protected void RadGrid1_NeedDataSource(object sender, Telerik.Web.UI.GridNeedDataSourceEventArgs e)
{
List<MyDataModel> datasource = new List<MyDataModel>();
for (i = 0; i <= 10; i++) {
datasource.Add(new MyDataModel {
Id = i,
Value = "Value" + i.ToString
});
}
((RadGrid)sender).DataSource = datasource;
}
I would first try with autogenerated columns on to make sure valid data is being returned from the NeedDataSource event, and then make sure your DataKeyNames and DataFields are valid properties. Additionally as #Seano666 said, because your grid is in an UpdatePanel any errors the RadGrid throws due to incorrect formatting will be suppressed.

Related

Trying to increment an integer on click of checkboxes

I'm having a scope problem (I think) trying to increment an integer.
I have several CheckBoxes, and want to limit users to only choose a maximum of three. So, I want to increment an integer on each checkbox click which I can check against.
My Default.aspx
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="chkRow" runat="server" autopostback="true" OnCheckedChanged="MyCheckBoxes_SelectedIndexChanged"/>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Title" />
<asp:BoundField DataField="Publisher" />
<asp:BoundField DataField="Genre" />
</Columns>
</asp:GridView>
My Default.aspx.cs
public partial class _Default : Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
DataSet ds = new DataSet();
ds.ReadXml(MapPath("App_Data/publications.xml"));
GridView1.DataSource = ds;
GridView1.DataBind();
}
}
private static int mycount = 0;
protected void MyCheckBoxes_SelectedIndexChanged(object sender, EventArgs e)
{
Label1.Text = mycount.ToString();
Increment(mycount);
}
public static void Increment(int mycount)
{
mycount++;
}
}
My Label1 is always displaying 0.
The names overlap inside the method scope of Increment. Remove mycount as parameter in Increment method

Get value of gridview.selected.row[] with visible property = 'false'

Hi from this field in my gridview, I'd like to pass the id value when the select command field is clicked, but i don't want to have the id field visible so I have the visible property set to false; however, when I pass it on the SelectedIndexChanged event the value is "" yet when the visible property is set to "true" the text value passes fine. What is the correct way to do this?
<asp:BoundField DataField="Project_ID" Visible="false"/>
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
String ProjID = GridView1.SelectedRow.Cells[10].Text;
}
Try this:
.aspx
<asp:Gridview id="GridView1" runat="server" DataKeyNames="Project_ID" />
.cs
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
if(gridView.SelectedDataKey != null)
{
var selectedId = GridView1.SelectedDataKey.Value;
}
}
Here you'll find more info about DataKeys in Gridviews: http://msdn.microsoft.com/de-de/library/system.web.ui.webcontrols.gridview.selecteddatakey(v=vs.110).aspx
I have done something like this in winform maybe can help you. That is what i used
int rowindex = dataGridView1.CurrentRow.Index;
string ProjID= dataGridView1.Rows[rowindex].Cells[10].Value.ToString();
you could use HiddenField inside your gridView ItemTemplate to keep the ID and use it in onrowcommand event, like below:
.aspx
<asp:GridView ID="gridProject" runat="server"
onrowcommand="gridProject_RowCommand">
<Columns>
<ItemTemplate>
<asp:HiddenField ID="hidProjectID" runat="server"
Value='<%# ((DataRowView)Container.DataItem)["Project_ID"] %>' />
<asp:Button ID="btnProject" runat="server" Text="use pro id"
CommandArgument="<%# ((GridViewRow) Container).RowIndex %>"
CommandName="DoSomething"></asp:Button>
</ItemTemplate>
</Columns>
</asp:GridView>
aspx.cs
protected void gridProject_RowCommand(object sender, GridViewCommandEventArgs e)
{
int index = 0;
GridViewRow gridRow;
GridView grid = sender as GridView;
try
{
switch (e.CommandName)
{
case "DoSomething":
index = Convert.ToInt32(e.CommandArgument);
row= gridProject.Rows[index];
string Id = ((HiddenField)row.FindControl("hidProjectID")).Value;
//do whatever you want here
break;
// and you can have as many commands as you want here
}
}
catch { //display error }
}

How to make visible a column of gridview?

I am using Gridview.In this i have 2 columns i.e. department and emailID.In this gridview department is bind from database and showed in linkbutton in gridview.
I want to do that when i clicked on thst dept linkbutton it make visible the column emailID.
How can i do this?Plaese guide me..
Thanks in advance.
Here is My Grid:
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="lnkbtnDept" runat="server" Text='<%#Bind("Department")%>' OnClick="lnkbtnTitle_Click" ></asp:LinkButton>
</ItemTemplate>
<ItemStyle HorizontalAlign="Left" Width="50%" />
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Panel ID="pnlN24" runat="server" Visible="false">
<asp:Label ID="lblTotal" runat="server" Width="30" Text="abc"></asp:Label>
</asp:Panel>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
You have to handle the events of GridView control especially RowCommand.
public class Demo
{
public string Dept { get; set; }
public string Email { get; set; }
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
List<Demo> list = new List<Demo>()
{
new Demo() { Dept="A", Email="a#a.com" },
new Demo() { Dept="B", Email="b#b.com" },
};
GridView1.DataSource = list;
GridView1.DataBind();
}
}
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "cmd")
{
GridViewRow row = (e.CommandSource as LinkButton).NamingContainer as GridViewRow;
Label email = row.Cells[1].FindControl("email") as Label;
email.Visible = true;
}
}
Understanding that you will make visible all the cells in the column for all the rows, you can handle the OnClick event of the dept button. For example.
<asp:LinkButton ID="lnkDept" OnClick="LinkButton_Click" runat="server" Text="Department" />
Code behind:
protected void LinkButton_Click(Object sender, EventArgs e)
{
gridView1.Columns[1].Visible=true;
}
Where gridView.Column[1] is your email column.
its not possible to make cell visible when column's visibility property set to false. so for showing only adjacent cell visible .
you can use the only one column of type template field and then make a table in that template field and set the td of email to visible false and on row command of grid as the previous answers making that lable visible you should make your td visible .
protected void lnkbtnTitle_Click(object sender, EventArgs e)
{
GridViewRow gvrow = ((LinkButton)sender).Parent.Parent as GridViewRow;
Panel pnlN24 = (Panel)gvrow.FindControl("pnlN24");
pnlN24.Visible = true;
}
It is very simple , the above code will work.
We have to find in which row the LinkButton is Clicked , which we can get from the
the following code. Once you get the GridViewRow then find the control in that row and make it Visible
GridViewRow gvrow = ((LinkButton)sender).Parent.Parent as GridViewRow;
As we know that
Control <--- Cell <-- GridViewRow <-- GridView
For Eg:
LinkButton <--- Cell <-- GridViewRow <-- GridView
GridViewRow is Parent to Cell and Cell is Parent to the Control inside the Cell (Panel)
function validateColors(id) {
var grid = document.getElementById("GridView1");
var label = grid.rows[id].cells[6].children[2];
grid.rows[id].cells[6].children[2].style.visibility = "visible";
grid.rows[id].cells[6].children[2].style.visibility = "hidden";
}

GridView event raise unexpectedly after postback

Consider this Asp.net page code:
<head runat="server">
<title></title>
<script type="text/javascript">
function showhide(master, detail) {
var src = $(master).children()[0].src;
if (src.endsWith("plus.png"))
src = src.replace('plus.png', 'minus.png');
else
src = src.replace('minus.png', 'plus.png');
$(master).children()[0].src = src;
$(detail).slideToggle("normal");
}
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Scripts>
<asp:ScriptReference Path="~/scripts/jquery-1.6.2.min.js" ScriptMode="Release" />
</Scripts>
</asp:ScriptManager>
<div>
<asp:SqlDataSource ID="sqlDsCustomers" runat="server" ConnectionString="<%$ ConnectionStrings:Northwind %>"
SelectCommand="SELECT [Customers].[CustomerID], [Customers].[CompanyName], COUNT([OrderID]) TotalOrders
FROM [Customers] INNER JOIN [Orders] ON [Customers].[CustomerID]=[Orders].[CustomerID]
Group By [Customers].[CustomerID], [Customers].[CompanyName]">
</asp:SqlDataSource>
<asp:GridView Width="100%" AllowPaging="True" ID="gvCustomers" AutoGenerateColumns="False"
DataSourceID="sqlDsCustomers" runat="server" ShowHeader="False" OnRowCreated="gvCustomers_RowCreated">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<div class="group" id='<%#String.Format("customer{0}",Container.DataItemIndex) %>'
onclick='showhide(<%#String.Format("\"#customer{0}\"",Container.DataItemIndex) %>,<%#String.Format("\"#order{0}\"",Container.DataItemIndex) %>)'>
<asp:Image ID="imgCollapsible" CssClass="first" ImageUrl="~/Assets/img/plus.png"
Style="margin-right: 5px;" runat="server" /><span class="header">
<%#Eval("CustomerID")%>
:
<%#Eval("CompanyName")%>
(<%#Eval("TotalOrders")%>Orders) </span>
</div>
<div id='<%#String.Format("order{0}",Container.DataItemIndex) %>' class="order">
<asp:GridView AutoGenerateColumns="false" CssClass="grid" ID="ddd" runat="server"
ShowHeader="true" EnableViewState="false">
<RowStyle CssClass="row" />
<AlternatingRowStyle CssClass="altrow" />
<Columns>
<asp:TemplateField ItemStyle-CssClass="rownum">
<ItemTemplate>
<%# Container.DataItemIndex + 1 %>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField HeaderText="Order ID" DataField="OrderID" ItemStyle-Width="80px" />
<asp:BoundField HeaderText="Date Ordered" DataField="OrderDate" DataFormatString="{0:MM/dd/yyyy}"
ItemStyle-Width="100px" />
<asp:BoundField HeaderText="Date Required" DataField="RequiredDate" DataFormatString="{0:MM/dd/yyyy}"
ItemStyle-Width="110px" />
<asp:BoundField HeaderText="Freight" DataField="Freight" DataFormatString="{0:c}"
ItemStyle-Width="50px" ItemStyle-HorizontalAlign="Right" />
<asp:BoundField HeaderText="Date Shipped" DataField="ShippedDate" DataFormatString="{0:MM/dd/yyyy}"
ItemStyle-Width="100px" />
</Columns>
</asp:GridView>
</div>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
<asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Button" />
</form>
and the code behind:
protected void Page_Load(object sender, EventArgs e)
{
}
protected void gvCustomers_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
string custID = ((DataRowView)e.Row.DataItem)["CustomerID"].ToString();
using (DataClassesDataContext dc=new DataClassesDataContext())
{
List<Order> ord = (from o in dc.Orders
where o.CustomerID == custID.Trim()
select o).ToList();
GridView ctrl = e.Row.FindControl("ddd") as GridView;
ctrl.DataSource = ord;
}
}
}
protected void Button1_Click(object sender, EventArgs e)
{
Response.Redirect("Default.aspx");
}
the problem is when I Click on Button1 to redirect to another page gvCustomers_RowCreated raise and I get Null reference error.Why this event raised after postback?
EDIT 1):
I removed SqlDataSource and bind GridView in the code behind like this:
public partial class Default2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
using (DataClassesDataContext dc=new DataClassesDataContext())
{
var query = dc.ExecuteQuery<clsRetern>("SELECT [Customers].[CustomerID], [Customers].[CompanyName], COUNT([OrderID]) TotalOrders FROM [Customers] INNER JOIN [Orders] ON [Customers].[CustomerID]=[Orders].[CustomerID] Group By [Customers].[CustomerID], [Customers].[CompanyName]").ToList();
List<clsRetern> ret = new List<clsRetern>();
foreach (var item in query)
{
clsRetern r = new clsRetern();
r.CompanyName = item.CompanyName;
r.CustomerID = item.CustomerID;
r.TotalOrders = item.TotalOrders;
ret.Add(r);
}
gvCustomers.DataSource = ret;
gvCustomers.DataBind();
}
}
}
protected void gvCustomers_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
string custID = ((clsRetern)e.Row.DataItem).CustomerID.Trim();
using (DataClassesDataContext dc=new DataClassesDataContext())
{
List<Order> ord = (from o in dc.Orders
where o.CustomerID == custID.Trim()
select o).ToList();
GridView ctrl = e.Row.FindControl("ddd") as GridView;
ctrl.DataSource = ord;
}
}
}
protected void Button1_Click(object sender, EventArgs e)
{
Response.Redirect("Default.aspx",true);
}
}
public class clsRetern
{
public string CustomerID { get; set; }
public string CompanyName { get; set; }
public int TotalOrders { get; set; }
}
I tried Response.Redirect("Default.aspx"); but the problem still remains.
If you understand ASP.NET page model then this question should not come to you. Every time request goes to ASP.NET page, a new page object is created along with entire control tree and the state is managed using view-state in post-back scenarios. So in your case, whenever post-back happens, a new page and grid-view is created. The data for the gid-view would be persisted in thew view-state and grid would be bound to that data.
The RowCreated event is raised whenever grid row is created regardless of whether DataBind is explicitly called or not. The intent of the event is so that one can tweak with UI (grid-view cells) - e.g. some controls can be pushed into grid-view cells if required. The same should happen regardless of post-back scenario other wise those dynamic controls will not get created. Typically, these controls will restore their state using view-state and your get your grid-view UI (control tree) back as it was in first page cycle.
Thats because even if you fire Response.Redirect, the Page_Load event would still be raised and if your GridView binding code is not inside !IsPostBack, that code will be hit.
Try this.
protected void Page_Load(object sender, EventArgs e)
{
try
{
if (!IsPostBack)
{
//bind gridview here
}
}
catch (Exception exception)
{
//Elmah.ErrorSignal.FromCurrentContext().Raise(exception);
}
}
Savvy?
Add EnableViewState=False to the page directive to prevent "RowCreated" running on every post back.

How can I two-way bind a TextBox to a code-behind property in ASP.NET?

I cannot get any new entries in the textbox:txtMyString to set to the property MyString. What am I missing here?
<asp:TextBox ID="txtMyString" Text='<%# MyString %>' runat="server" />
private string myString;
protected string MyString { get { return myString; } set { myString = value; } }
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
myString = "1 way test works";
DataBind();
}
If you're doing two-way databinding, you need to use the Bind() method of the databinder.
<asp:TextBox ID="txtMyString" Text='<%# Bind("MyString") %>' runat="server" />
However, last time I checked, this was only supported if the textbox was inside a templated control such as Gridview, FormView or DetailsView.

Resources