Edit, Delete and Insert in a programmatically created GridView - c#

So I'm facing a problem. In fact i have created a databound GridView programmatically. The problem is I want to be interactive (update , delete, insert and all that drill) but only using c# since i have created it programmatically.
Here is the code that'ive created with the GridView
GridView grid = new GridView();
//CSS
grid.CssClass = "grid";
grid.ForeColor = System.Drawing.Color.Gray;
grid.ShowFooter = true;
grid.AlternatingRowStyle.CssClass = "gridAltRow";
grid.RowStyle.CssClass = "gridRow";
grid.FooterStyle.CssClass = "gridFooterRow";
grid.DataKeyNames = new string[] { "ID" };
grid.RowCommand
//End Css
grid.AutoGenerateEditButton = true;
grid.DataSource = element.GetElementByRubric(testrub.ID);
panel.Controls.Add(grid);
grid.DataBind();
TabContainer1.Tabs.Add(panel);
as you can see i added an edit button but it does nothing of course. Does anyone have any suggestions ??
thx

You have to write the function for updating the database in onrowupdating event of the gridview to make the edit link work.

Why are you generating a grid in code? This is highly unusual.
It may or may not be possible but why are you avoiding just writing the grid directly to the ASPX file?

You need to add a handler for the OnRowEditing event. Something similar to
grid.RowEditing+=new GridViewEditEventHandler(grid_RowEditing_RowEditing);
to attach the event handler and then an event handler like below. In this case the sender will be the dynamically created GridView.
protected void grid_RowEditing(object sender, GridViewEditEventArgs e)
{
((GridView)sender).EditIndex = e.NewEditIndex;
// Then call your databinding method here to update the grid.
}
This would also be the same method you would use to add handlers for the delete and insert events also.

Related

Trigger Grid row validation when selection of cell editor LookUpEdit changes

I have a DevExpress.XtraGrid.GridControl which has a column using DevExpress.XtraEditors.Repository.RepositoryItemLookUpEdit as cell editors.
When I select an item from the LookUpEdit, this does not cause any validation but does nothing until I click anywhere to make the Grid lose focus.
My desired behaviour would be that changing the LookUpEdit's selection immediately triggers a row validation event of the Grid.
How could this be achieved?
The official DevExpress Documentation tells to call the GridView's UpdateCurrentRow method:
There may be cases when you need to implement row validation. [...] To do so, handle the ColumnView.ValidateRow event. Note that you can also initiate row validation manually by calling the ColumnView.UpdateCurrentRow method.
I did this in the GridView's ValidatingEditor event handler:
private void gridView1_ValidatingEditor(object sender,BaseContainerValidateEditorEventArgs e)
{
(sender as GridView).UpdateCurrentRow();
}
However, now I can't add new rows to the Grid any more as end-user.
What would be the correct approach?
Update:
I am now listening to the GridView's CellValueChanging event and handling it like this:
private void gridView_CellValueChanging(object sender, CellValueChangedEventArgs e)
{
GridView gv = (sender as GridView);
gv.CellValueChanging -= gridView_CellValueChanging; // detach this event handler
gv.ActiveEditor.EditValue = e.Value;
gv.CellValueChanging += gridView_CellValueChanging; // re-attach handler
gv.CloseEditor();
}
I am sure this is not the way how one should do it, but it works for existing rows. However, it does not work on the "new row" - I still have to click anywhere else to apply changes that create a new entry. I want a new row to be created as soon as any cell of the "new row" got edited.
The editor in the cell is still open, you have to close it.
private void lookup_Closed(object sender, EventArgs e)
{
gvMyGrid.CloseEditor();
gvMyGrid.UpdateCurrentRow();
}

C# - Update databound combo box automatically

So I've found a lot of questions similar to this tho nothing really solve my problem..
I have a combobx that is bounded by a datasource
cmbProduct.DataSource = this.masterDataSet.Product.Where(x => x.Location == getLocation).AsDataView();
cmbProduct.DisplayMember = "Product";
cmbProduct.ValueMember = "Product";
But whenever i update the source, the combobox items does not update automatically. I still need to close then reopen the form.
is there a method to refresh/reload/or update the combobox?
Solution 1
You can use an implementation of IBindingList as DataSource to view changes of data source in the bound list control (complex two-way data binding). The most suitable implementation is System.ComponentModel.BindingList<T>.
Then when you add items to the binding list, or remove item from it you will see changes immediately in the control.
Solution 2
But as a more simple solution with less changes for you, you can reset the databinding of your cmbProduct this way when you need; for example after a change, call RefreshBindings();:
public void RefreshBindings()
{
var list = put your updated list here;
this.cmbProduct.DataSource = null;
this.cmbProduct.DataSource = list;
this.cmbProduct.DisplayMember = "set the display member here";
this.cmbProduct.ValueMember = "set the value member here";
}
You could implement an event that fires whenever the DataSet changes. The event could reset the Datasource and rebind it.
Somewhere in your code:
yourDataController.DataChanged += OnDataChanged;
and the implementation
public void OnDataChanged(object sender, EventArgs e)
{
cmbProduct.Items.Clear();
cmbProduct.DataSource = this.masterDataSet.Product.Where(x => x.Location == getLocation).AsDataView();
cmbProduct.DisplayMember = "Product";
cmbProduct.ValueMember = "Product";
}
Edit: Of course you need to manually implement the event and cause it to fire every time your data changes.

DevExpress Unbound column event not firing, WinForms

I have created an unbound column which I intend to populate with calculated data; however, I am unable to get the CustomUnboundColumnData event to fire. I basically copied the code from DevExpress documentation on https://documentation.devexpress.com/#WindowsForms/CustomDocument1477
As per other posts found I made sure that there are no other columns with the same name.
The new unbound column does indeed appear in the grid, but the event is never firing so I don't know how to populate it.
In my constructor I define the columns as below: (I made sure there are no other columns with the same name)
GridColumn testColumn = new GridColumn();
testColumn.FieldName = "Test Column1";
testColumn.VisibleIndex = gridView1.Columns.Count;
testColumn.UnboundType = DevExpress.Data.UnboundColumnType.DateTime;
// Disable editing.
testColumn.OptionsColumn.AllowEdit = true;
// Specify format settings.
testColumn.DisplayFormat.FormatType = DevExpress.Utils.FormatType.DateTime;
testColumn.DisplayFormat.FormatString = "d";
testColumn.Visible = true;
gridView1.Columns.Add(testColumn);
Then I have my event function which never fires
private void gridView1_CustomUnboundColumnData(object sender, CustomColumnDataEventArgs e)
{
MessageBox.Show("unbound column a go go");
How can I populate the unbound column?
Solved thanks to DevExpress support forum (which is very nice by the way)
I was missing the line for gridView1.CustomUnboundColumnData += gridView1_CustomUnboundColumnData; which tells the grid which event handler(s) to use for unbound columns

asp.net drop down list duplicated itself when post back

It is a very weird problem
when I change the value of the drop down list, a new drop down list is show. I am so confused,
To know what I am talking about, please check these images.
edit
code for bind
CallerId = Request["CallerID"];
if (String.IsNullOrWhiteSpace(CallerId)) return;
var results = ZumaDa.GetCustomerInformation(CallerId);
rowCount = results.Rows.Count;
CallerId = rowCount > 0 ? results.Rows[0][4].ToString() : CallerId;
if (rowCount > 1)
{
ListView1.Enabled = false;
GridView1.DataSource = results;
GridView1.DataBind();
}
else
{
GridView1.Enabled = false;
ListView1.DataSource = results;
ListView1.DataBind();
}
That code is in page load and NOT on !ispostback
Since you updated your question with the ListView markup, and your Page_Load code, it appears the problem of the duplicated DropDownList goes away after you wrap your databinding code in an if (!Page.IsPostBack) block.
One problem in your code is that, in your SelectedIndexChanged event, you're searching the ListView for your DropDownList and TextBox. You need to search the ListViewItem control where the SelectedIndexChanged event occurred.
To do that, you can first get the DropDownList from the "sender" parameter. Then you should find the "NamingContainer" control of the DropDownList, and search that. Like this:
var dropDown = (DropDownList)sender;
var visitID = (TextBox)dropDown.NamingContainer.FindControl("visitID");
That second line of code might need to have an additional ".NamingContainer" depending on your markup.
I think you need to bind listview in !IsPostback check means when do postback it pageload event fired and it bind dropdown with second time or if its not please share binding code

How to add buttons to datagridview cells not entire column

How do you add a button to cells in a row and not the entire column in a datagridview?
I think Adrian's answer was close. Try something like this.
if ((string)table.Rows[0].Cells[0].Value == "I should be a button") {
// you can add formatting or values to the button before assigning it here
table.Rows[0].cells[0] = new DataGridViewButtonCell();
}
I think the best answer if found here:
Hide gridview button. All you need to do is to add a DataGridViewButtonCell where you want buttons, and DataGridViewTextBoxCell where you do not. The column has to be DataGridViewButton type.
See this similar post in SO, probably helps
adding control to gridview
In case Win Form, Check this MSDN post
Column Types in the Windows Forms DataGridView Control
OR this code project post ... though it gives example of adding a image button
DataGridView Image Button Cell
#tmax In that case you can probably put your button creation code in GridView_RowCreated event like below
void GridView_RowCreated(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.Header)
{
//Button creation code here
}
}
private void dataGridView1_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
{
Button btn = new Button();
//btn attributes
dataGridView1.Rows[0].Cells[3].Value = new Button();
}
try something like this.
What I endded up doing was stacking a DataGridView on top of another one. I turned off the border, gridlines, and scrollbars. Then create dynamic button columns to match the main datagridview with only one row of buttons. Then I used the ColumnWidthChanged event handler to resize both the DataGridViews together. Anyway's this was my workaround for now.
DataGridViewButtonColumn dataGridViewButtonColumn = new DataGridViewButtonColumn();
dataGridViewButtonColumn.Name = "Select";
dataGridViewButtonColumn.HeaderText = "Select";
dataGridViewButtonColumn.ReadOnly = false;
dataGridView1.Columns.Add(dataGridViewButtonColumn);
After assigning data source to gridviewCTRL. you can add new column with button with below code.
DataGridViewButtonColumn startbtn = new DataGridViewButtonColumn();
startbtn.Name = "Action";
startbtn.Text = "Start";
startbtn.UseColumnTextForButtonValue=true;
int columnIndex = 6;
gridviewCTRL.Columns.Insert(columnIndex, startbtn);
This will add the button to each and every row at define column index.
if you want to render condition the AccessibleObject, then you can do something similar to below.
foreach (DataGridViewRow rowdata in gridviewCTRL.Rows)
{
// this is just an example in my case i am checking a previous column value
if (rowdata.Cells[5].Value=="XYZ")
{
rowdata.Cells[6] = new DataGridViewTextBoxCell();
}
}
This way you can dynamically render/ showing the control in the GridView in Winforms c#.
The above code simple update the cell with new cell. We can't remove button from the cell nor remove whole, so instead we can initial a new cell that will override the button visibility.
I am not sure if this will help but you can also consider using TableLayoutPanel.
Refer: Winforms TableLayoutPanel adding rows programmatically

Categories