I work on northwind database. In my AspxGridview I want to show comboBox. I fill grid on back end C# I also want my combo will fill back end.
<dxwgv:ASPxGridView ID="ASPxGridView1" runat="server"
AutoGenerateColumns="False" KeyFieldName="CategoryID"
oncelleditorinitialize="ASPxGridView1_CellEditorInitialize">
<Columns>
<dxwgv:GridViewCommandColumn VisibleIndex="0" Width="80px">
<EditButton Visible="True">
</EditButton>
<NewButton Visible="True">
</NewButton>
<DeleteButton Visible="True">
</DeleteButton>
</dxwgv:GridViewCommandColumn>
<dxwgv:GridViewDataTextColumn Caption="CategoryID" FieldName="CategoryID"
VisibleIndex="1">
</dxwgv:GridViewDataTextColumn>
<dxwgv:GridViewDataComboBoxColumn Caption="CategoryName"
FieldName="CategoryName" VisibleIndex="2">
<PropertiesComboBox TextField="Value" ValueField="key" ValueType="System.Int32">
<ClientSideEvents SelectedIndexChanged="function(s, e) { OnBankChanged(s); }" />
</PropertiesComboBox>
</dxwgv:GridViewDataComboBoxColumn>
<dxwgv:GridViewDataTextColumn Caption="Description" FieldName="Description"
VisibleIndex="3">
</dxwgv:GridViewDataTextColumn>
</Columns>
</dxwgv:ASPxGridView>
To fill grid i use the bellow C# syntax.
DataClasses1DataContext db = new DataClasses1DataContext();
var r = from p in db.Categories
select p;
ASPxGridView1.DataSource = r;
ASPxGridView1.DataBind();
To fill gridview cell of combo i use Bellow C# syntax
protected void ASPxGridView1_CellEditorInitialize(object sender, DevExpress.Web.ASPxGridView.ASPxGridViewEditorEventArgs e)
{
if (!ASPxGridView1.IsEditing || e.Column.FieldName != "CategoryID") return;
ASPxComboBox combo = e.Editor as ASPxComboBox;
if (!(e.KeyValue == DBNull.Value || e.KeyValue == null)) //return;
{
object val = ASPxGridView1.GetRowValuesByKeyValue(e.KeyValue, "CategoryID");
if (val == DBNull.Value) return;
Int32 CategoryID = (Int32)val;
FillCityCombo(combo, CategoryID);
}
combo.Callback += new CallbackEventHandlerBase(cmbBranch_OnCallback);
}
private void cmbBranch_OnCallback(object source, CallbackEventArgsBase e)
{
FillCityCombo(source as ASPxComboBox, Convert.ToInt16(e.Parameter));
}
protected void FillCityCombo(ASPxComboBox cmb, Int32 CategoryID)
{
//cmb.Items.Clear();
//cmb.DataSourceID = "";
DataClasses1DataContext db = new DataClasses1DataContext();
var r = from p in db.Categories
select new { p.CategoryID,p.CategoryName};
cmb.DataSource = r;
cmb.DataBind();
}
When I run the code AspxGridview fill well but when I click on Edit or New Command on left side of my grid shows me error message below:
**Object reference not set to an instance of an object.**
What's the problem?
How to solve this problem?
How to bind cell combo on aspx gridview?
This is the cause of this issue. You are checking for the "CategoryID" field name. But the ComboBox column is created for the "CategoryName" field:
if (!ASPxGridView1.IsEditing || e.Column.FieldName != "CategoryID") return;
ASPxComboBox combo = e.Editor as ASPxComboBox;
We've posted a sample project showing how to implement dependent combos in insert mode at:
http://www.devexpress.com/Support/Center/ViewIssue.aspx?issueid=Q102130
I hope, this project will be helpful to you.
Bind in the OnRowDataBound event (or AspxGridview equivalent)
Related
I am using one aspxGridview where I used checkbox. Now I need when I check any of the row particular column value I should get in server side to complete my business logic.
Below is the gridview used:
<dx:ASPxGridView KeyFieldName="PracticeID" ID="ASPxGrd" runat="server" ClientInstanceName="grid"
ClientIDMode="AutoID" AutoGenerateColumns="false" Width="100%" OnSelectionChanged="ASPxGrd_SelectionChanged">
<Columns>
<dx:GridViewDataColumn VisibleIndex="0" Name="CheckBoxColumn">
<DataItemTemplate>
<dx:ASPxCheckBox ID="ASPxCheckBox1" runat="server" OnCheckedChanged="ASPxCheckBox1_CheckedChanged" AutoPostBack="true">
</dx:ASPxCheckBox>
</DataItemTemplate>
</dx:GridViewDataColumn>
<dx:GridViewDataColumn FieldName="PracticeName" Caption="Description" VisibleIndex="1">
<FooterTemplate>
Total:
</FooterTemplate>
</dx:GridViewDataColumn>
</dx:ASPxGridView>
I have tried to use oncheckedevent in checkbox with auto postback true and used code to get selected row like below:
protected void ASPxCheckBox1_CheckedChanged(object sender, EventArgs e)
{
ASPxGridView grid = sender as ASPxGridView;
string currentMasterKey = Convert.ToString(grid.GetMasterRowKeyValue());
}
but getting null value of grid object.
Need help.
In your example you have used DataItemTemplate, so in that case the sender will be the control which is added in that data template i.e ASPxCheckBox and you are casting it to grid bcoz of that it is getting null.
try out below snippet.
protected void ASPxCheckBox1_CheckedChanged(object sender, EventArgs e)
{
ASPxCheckBox checkBox = sender as ASPxCheckBox;
var grid = (checkBox.NamingContainer as DevExpress.Web.ASPxGridView.GridViewDataItemTemplateContainer).Grid;
string currentMasterKey = Convert.ToString(grid.GetMasterRowKeyValue());
}
I found this answer before and it's working fine like below:
for (int i = 0; i < ASPxGrd.VisibleRowCount; i++)
{
ASPxCheckBox chk = ASPxGrd.FindRowCellTemplateControl(i, null, "ASPxCheckBox1") as ASPxCheckBox;
if (chk.Checked)
{
if (i == 0)
{
practiceName = ASPxGrd.GetRowValues(i, "PracticeName").ToString();
}
}
}
using this code i am able to get selected checkbox column value.
I have a GridView which I dynamically add rows to through the button_OnClick event, this adds a new row with the Product name & Product ID from a DropDownList and also contains a column with an empty text box for user input.
My problem is that when I test it and enter data in the text box, then add another Product, the post back causes my data to be lost (the correct number of rows are still there with product names / ids).
<asp:GridView runat="server" ID="grdSelectedProducts" BorderWidth="1px" CellPadding="3" CellSpacing="2" AutoGenerateColumns="False" OnRowDataBound="grdSelectedProducts_OnRowDataBound" ShowHeaderWhenEmpty="True" DataKeyNames="ProductId"
OnRowCommand="grdSelectedProducts_RowCommand" OnRowDeleted="grdSelectedProducts_RowDeleted" OnRowDeleting="grdSelectedProducts_RowDeleting" EmptyDataText="Please select a Product and click 'Add'" EnableViewState="True">
<Columns>
<asp:BoundField DataField="Product" HeaderText="Product" ReadOnly="False"/>
<asp:TemplateField HeaderText="Description">
<ItemTemplate>
<asp:TextBox runat="server" ID="txtDescriptionEntry" Text="" style="width:98% !important" EnableViewState="True"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton runat="server" ID="linkDelete" runat="server" CommandName="Delete" CommandArgument="<%# Container.DataItemIndex %>">Remove</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="ProductId" HeaderText="ProductId" ReadOnly="False" Visible="False" />
</Columns>
</asp:GridView>
How can I avoid postback scrapping the data on each txtDescriptionEntry that is created? There could be between 0 and an infinite number of these text boxes, so I won't have exact names at any one time.
Edit, as per a comment below I'm including the code for how I add rows to the grid:
private DataTable ProductDataTable
{
get {return ViewState["ProductDataTable"] as DataTable ?? new DataTable(); }
set { ViewState["ProductDataTable"] = value; }
}
private DataTable CreateDataTable(bool isAddingValue, string selectedProduct, string selectedId)
{
// if isAddingValue is FALSE then it isn't from a button click to add a Product, it is just
// a call to create the datatable
DataTable dataTable = ProductDataTable;
if (!dataTable.Columns.Contains("Product"))
{
dataTable.Columns.Add("Product");
dataTable.Columns.Add("Description"); // This column is free format text that the user enters.
dataTable.Columns.Add("ProductId");
}
if (isAddingValue)
{
// Get the data from ViewState
//dataTable = ProductDataTable;
DataRow dataRow;
dataRow = dataTable.NewRow();
dataRow["Product"] = selectedProduct;
dataRow["ProductId"] = selectedId;
dataTable.Rows.Add(dataRow);
}
else
{
grdSelectedProducts.DataSource = null;
grdSelectedProducts.DataSource = ProductDataTable;
grdSelectedProducts.DataBind();
}
// Save the data back to ViewState
ProductDataTable = dataTable;
return dataTable;
}
protected void btnAddProduct_OnClick(object sender, EventArgs e)
{
string selectedProduct = ddlProduct.SelectedItem.Text;
string selectedId = ddlProduct.SelectedValue;
DataTable dataTable = CreateDataTable(true, selectedProduct, selectedId);
grdSelectedProducts.DataSource = dataTable;
grdSelectedProducts.DataBind();
}
protected void grdSelectedProducts_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Delete")
{
if (!string.IsNullOrEmpty(e.CommandArgument.ToString()))
{
int rowIndex = Convert.ToInt32(e.CommandArgument);
DataTable table = CreateDataTable(false, string.Empty, string.Empty);
table.Rows.RemoveAt(rowIndex);
grdSelectedProducts.DataSource = table;
grdSelectedProducts.DataBind();
}
}
}
And in the Page_Load event, if it isn't a PostBack there is also binding of an empty list
grdSelectedProducts.DataSource = new List<Products>();
grdSelectedProducts.DataBind();
I figured this out, not the nicest solution (so I probably wouldn't recommend it) but it got me out of a jam.
I used the OnRowDataBound event so for each row that was being bound to the table I would use the RowIndex to get the appropriate row in the DataTable, I would then assign the text box (also obtained via the index) the value from the DT. Example below.
protected void grdSelectedproducts_OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowIndex > -1)
{
TextBox txtDescription = e.Row.FindControl("txtDescriptionEntry") as TextBox;
if (txtDescription != null)
{
DataTable dt = ProductDataTable;
DataRow row = dt.Rows[e.Row.RowIndex] as DataRow;
txtDescription.Text = row[1].ToString();
}
}
}
I have tried so many times but i am not able to delete a row in GRID VIEW. I didn't create any database.I am just storing all the values of the text field in the GRID VIEW.If i want to delete a row in the GRID VIEW using template field button means,what will be the solution.
This is the way i am storing and populating values in GridView.
DataSet ds = new DataSet();
DataRow dr = ds.Tables[0].NewRow();
dr[0] = lbltxtcustomer.Text;
dr[1] = FNtxt.Text;
dr[2] = LNtxt.Text;
dr[3] = DrpdownMonth.Text + "/" + DrpdownDay.Text + "/" + DrpdownYear.Text;
dr[4] = lbltxtage.Text;
dr[5] = txtEmail.Text;
dr[6] = TxtPhone.Text;
dr[7] = Txtlocation.Text;
ds.Tables[0].Rows.Add(dr);
BindGrid()
;
Try This
HTML Markup
Below is the HTML Markup of the APS.Net GridView. Here I am making use the CommandFieldand OnRowDeleting event to delete the GridView Row. Hence I will apply the JavaScript Confirmation Box to the CommandFieldDelete Button itself.
<asp:GridView ID="GridView1" CssClass = "Grid" runat="server" OnRowDeleting="OnRowDeleting" AutoGenerateColumns = "false" OnRowDataBound = "OnRowDataBound">
<Columns>
<asp:BoundField DataField="Item" HeaderText="Item" />
<asp:BoundField DataField="Price" HeaderText="Price" />
<asp:CommandField ShowDeleteButton="True" ButtonType="Button" />
</Columns>
</asp:GridView>
Applying the JavaScript Confirmation Box to the GridView CommandField
Delete Button
To apply the JavaScript Confirmation Box, I am looking for the Button in the Controls of the GridView Cell Index 2 since it has the CommandField. Once
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
string item = e.Row.Cells[0].Text;
foreach (Button button in e.Row.Cells[2].Controls.OfType<Button>())
{
if (button.CommandName == "Delete")
{
button.Attributes["onclick"] = "if(!confirm('Do you want to delete " + item + "?')){ return false; };";
}
}
}
}
Delete the ASP.Net GridView Row using CommandField and OnRowDeleting
event
Below is the code to delete the ASP.Net GridView Row using OnRowDeleting event
protected void OnRowDeleting(object sender, GridViewDeleteEventArgs e)
{
int index = Convert.ToInt32(e.RowIndex);
DataTable dt = ViewState["dt"] as DataTable;
dt.Rows[index].Delete();
ViewState["dt"] = dt;
BindGrid();
}
Thru radio button i am selecting the data from gridview. Here all radio buttons are selectable at a time. Actually it should not happen at a time user can select only one button which i could not do. My second problem is when i am selecting particular radiobutton that details should be displayed in text box. I have Itemid, ItemName, Quantity, Rate and Total field in gridview. These values i have inserted thru textbox so i have all the corresponding text box for all. So once i select particular radiobutton those details should be displayed in corresponding textbox. I have done the insertion coding for this but couldn't do selecting thru radiobutton and dispalying in textbox. Pls somebody help me in coding for this problem.
Thanks,
sumit
Sumit,
Don't use the html control, use the asp control:
<asp:RadioButton ID="RadioSelector" runat="server" GroupName="RadioSelectors" />
I had a similar problem in an ASP.NET class, and I followed this tutorial which worked perfectly.
Sounds like the classic master/detail pattern see here:
Tutorial 10: Master/Detail Using a Selectable Master GridView with a Details DetailView
You are fighting the intended workings of ASP.NET databound controls by using radio buttons. I don't like having select links either they're not exactly Web 2.0! but they can be quite easily replaced with a row click by doing this (or variation of same):
Select a row in an asp:GridView without using a Select Command
I read several articles on the net but none were suitable. I finally figured out my own solution without using either HTMLControls radiobutton nor using Javascript. This works for my requirement.
My Gridview html settings were as follows
<asp:GridView ID="grdVersion" runat="server"
AutoGenerateColumns="false" AllowPaging="true"
AutoGenerateEditButton="false" PageSize="10" Width="400px"
EmptyDataText="No records available."
OnRowDataBound="grdVersion_RowDataBound"
AutoGenerateSelectButton="false">
<Columns>
<asp:BoundField DataField="versionid" HeaderText="Version No." ItemStyle-Width="50px"
ItemStyle-Wrap="false" HtmlEncode="true" ReadOnly="true" />
<asp:BoundField DataField="version_date" HeaderText="Version Date" ItemStyle-Width="100px"
ItemStyle-Wrap="false" HtmlEncode="true" ReadOnly="true" />
<asp:BoundField DataField="remarks" HeaderText="Remarks" ItemStyle-Width="150px"
ItemStyle-Wrap="true" HtmlEncode="true" ReadOnly="true" />
**<asp:TemplateField HeaderText="Admin" HeaderStyle-Width="100px">
<ItemTemplate>
<asp:RadioButton ID="rdCurrent" runat="server"
Checked="false" Enabled="true" GroupName="rgVersion"
AutoPostBack="true"
OnCheckedChanged="rdCurrent_CheckChanged" />
</ItemTemplate>**
</asp:TemplateField>
</Columns>
</asp:GridView>
The server code (C#) was as follows,
DataTable dtDataSpaceVersions; //place this inside the codebehind page class
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
dtDataSpaceVersions = ListDataSpaceVersions();
ViewState["dtDataSpaceVersions"] = dtDataSpaceVersions;
PopulateGridVersion();
}
}
protected void PopulateGridVersion()
{
grdVersion.DataSource = dtDataSpaceVersions;
grdVersion.DataBind();
}
protected void rdCurrent_CheckChanged(object sender, EventArgs e)
{
Control selectedVersion = ((Control)sender).Parent;
if (ViewState["dtDataSpaceVersions"] != null)
dtDataSpaceVersions = (DataTable)ViewState["dtDataSpaceVersions"];
foreach (DataRow dtr in dtDataSpaceVersions.Rows)
{
if (dtr["versionid"].ToString() == ((System.Web.UI.WebControls.GridViewRow)selectedVersion.Parent).Cells[0].Text)
dtr[3] = "Y";
else
dtr[3] = "N";
}
PopulateGridVersion();
}
protected void grdVersion_RowDataBound(object sender, GridViewRowEventArgs e)
{
DataRowView drv;
if (e.Row.RowType == DataControlRowType.DataRow && e.Row.DataItem != null)
{
drv = (DataRowView)e.Row.DataItem;
if ((RadioButton)(e.Row.FindControl("rdCurrent")) != null)
if (drv.Row.ItemArray[3].ToString() == YesNo.N.ToString())
((RadioButton)(e.Row.FindControl("rdCurrent"))).Checked = false;
else
((RadioButton)(e.Row.FindControl("rdCurrent"))).Checked = true;
//setGridUserPermissionCheckBoxState(e.Row, drv);
}
}
public DataTable ListDataSpaceVersions()
{
string sql = string.Empty;
DataTable dt = new DataTable();
dt.Columns.Add("versionid", typeof(String));
dt.Columns.Add("version_date", typeof(String));
dt.Columns.Add("remarks", typeof(String));
dt.Columns.Add("is_current", typeof(String));
DataRow dtr;
dtr = dt.NewRow();
dtr[0] = "1.1";
dtr[1] = "12-Dec-2005";
dtr[2] = "Campaign Information";
dtr[3] = "N";
dt.Rows.Add(dtr);
dtr = dt.NewRow();
dtr[0] = "1.2";
dtr[1] = "06-Mar-2006";
dtr[2] = "Sales corrections";
dtr[3] = "N";
dt.Rows.Add(dtr);
dtr = dt.NewRow();
dtr[0] = "1.3";
dtr[1] = "24-Aug-2009";
dtr[2] = "Invoice reconciliation";
dtr[3] = "Y";
dt.Rows.Add(dtr);
dtr = dt.NewRow();
dtr[0] = "1.4";
dtr[1] = "30-May-2010";
dtr[2] = "Invoices verification";
dtr[3] = "N";
//dtr[0][0] = "";
dt.Rows.Add(dtr);
return dt;
}
I have a GridView...
<asp:GridView EnableViewState="true"
ID="grdResults"
runat="server"
CssClass="resultsGrid"
OnRowDataBound="grdResults_OnRowDataBound"
AutoGenerateColumns="false"
HeaderStyle-CssClass="header"
OnRowCommand="grdResults_OnRowCommand">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="lblView"
runat="server"
Visible="false"
Text="View">
</asp:Label>
<asp:HyperLink ID="hypEdit"
runat="server"
Visible="false"
Text="(Edit)"
CssClass="edit">
</asp:HyperLink>
<asp:LinkButton ID="btnDelete"
runat="server"
Visible="false"
Text="(Delete)"
CssClass="delete"
CommandName="DeleteItem"
OnClientClick="return confirm('Are you sure you want to delete?')">
</asp:LinkButton>
<asp:HyperLink ID="hypSelect"
runat="server"
Visible="false"
Text="(Select)"
CssClass="select">
</asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
This has one static column containing a label two hyperlinks and a link button and also has a number of dynamically generated columns...
private void SetupColumnStructure(IEnumerable<string> columnNames)
{
var columnNumber = 0;
foreach (var columnName in columnNames)
{
var templateColumn = new TemplateField
{
ItemTemplate = new CellTemplate(columnName)
};
grdResults.Columns.Insert(columnNumber, templateColumn);
columnNumber++;
}
}
As part of the OnRowDataBound handler I retrieve one of the controls in the statically column and set some attributes on it...
protected void grdResults_OnRowDataBound(object sender, GridViewRowEventArgs e)
{
.
.
.
var row = e.Row;
var rowData = row.DataItem as Dictionary<string, object>;
if (rowData != null)
{
if ((bool)rowData[displayEditLink])
{
var hypEdit = (HyperLink)row.FindControl("hypEdit");
hypEdit.NavigateUrl = "~/Pages/Edit.aspx?action=Edit&objectType=" + rowData[objectTypeLiteral] + "&id=" + rowData[objectIdLiteral];
hypEdit.Visible = true;
}
}
.
.
.
}
This all works fine but no column names are displayed. So I then modify the SetupColumnStructure method so that the HeaderText is set on the template field like this...
private void SetupColumnStructure(IEnumerable<string> columnNames)
{
var columnNumber = 0;
foreach (var columnName in columnNames)
{
var templateColumn = new TemplateField
{
ItemTemplate = new CellTemplate(columnName),
HeaderText = columnName
};
grdResults.Columns.Insert(columnNumber, templateColumn);
columnNumber++;
}
}
For some reason this one extra line change causes the row.FindControl("hypEdit"); call in the OnRowDataBound handler to return null.Can anyone see something im missing here or has anyone experienced a similar issue?
UPDATE
I've made sure that I'm not referring to a header or footer row here. Also, if I step over the object reference exception this occurs for every item that is in the DataSource.
Not sure if this helps, but as I expected, when I stepped through the code the table has generated all the columns expected but all cells (DataControlFieldCells) contain no controls when the HeaderText is set, yet all expected controls when it isnt set.
All very strange. Let me know if you can spot anything else.
When you added the HeaderText, a new RowType was added to the gridview. You'll need to check what type of row raised the OnRowDataBound event and take the appropriate action. In your case, just checking if the e.Row.RowType is a DataRow should solve your problem:
protected void grdResults_OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
if ((bool)rowData[displayEditLink])
{
var hypEdit = (HyperLink)row.FindControl("hypEdit");
hypEdit.NavigateUrl = "~/Pages/Edit.aspx?action=Edit&objectType=" + rowData[objectTypeLiteral] + "&id=" + rowData[objectIdLiteral];
hypEdit.Visible = true;
}
}
}
Its because the control you are searching for is contained within another control. FindControl() does not look inside control collections of controls. You will need to write a recursiveFindControl() method.
Hope this helps a little!