RadComboBox SelectedIndexChanged event not firing when using inplace editing in a RadGrid - c#

I am using inplace editing on a RadGrid that is built using a class file. Everything is working well except I am having an issue the SelectedIndexChanged event not firing when the grid is in edit mode. Any thoughts?
private void RadGrid_ItemCreated(object sender, GridItemEventArgs e)
{
if (e.Item is GridEditableItem && e.Item.IsInEditMode)
{
try
{
if ((e.Item as GridDataItem) == null) { return; }
((RadNumericTextBox) (e.Item as GridDataItem)["Percentage"].Controls[0]).Width = Unit.Pixel(75);
((TextBox) (e.Item as GridDataItem)["Code"].Controls[0]).Width = Unit.Pixel(75);
RadComboBox _participantList = (e.Item as GridEditableItem)["ID"].Controls[0] as RadComboBox;
if (null == _participantList) { return; }
_participantList.Width = Unit.Pixel(120);
_participantList.DataValueField = "ID";
_participantList.DataTextField = "ID";
_participantList.AutoPostBack = true;
_participantList.DataSource = MAASBaseInterface.ParticipantAPI.GetParticipants();
_participantList.DataBind();
_participantList.SelectedIndexChanged += new RadComboBoxSelectedIndexChangedEventHandler(_participantList_SelectedIndexChanged);
if (!(e.Item.DataItem is GridInsertionObject))
_participantList.SelectedValue = ((Participant) (e.Item.DataItem)).ID.ToString();
if (e.Item.DataItem is GridInsertionObject)
_participantList.EmptyMessage = "-- Select --";
}
catch (Exception ex)
{
string _ex = ex.Message;
}
}
}
void _participantList_SelectedIndexChanged(object sender, RadComboBoxSelectedIndexChangedEventArgs e)
{
//first reference the edited grid item through the NamingContainer attribute
GridEditableItem editedItem = (sender as RadComboBox).NamingContainer as GridEditableItem;
int _selectedValue = Convert.ToInt32((editedItem["ID"].Controls[0] as RadComboBox).SelectedValue);
ParticipantList _participants = MAASBaseInterface.ParticipantAPI.GetParticipants();
Participant _participant = _participants.Where(a => a.ID == _selectedValue) as Participant;
RadTextBox _code = editedItem["Code"].Controls[0] as RadTextBox;
_code.ReadOnly = false;
_code.Text = _participant.Code;
}

You need a button that has the CommandName="Select" set. Without that the event doesn't trigger. Could that be the problem?
This link gives more detail
EDIT:
The problem might be that the dropdown list is dynamically added to the grid so that the event needs to be added each time the row is bound. In my experience the radGrid and the GridView works in the same way with respect to the event model so this SO answer might sort you out. Good luck - my initial thoughs were that this couldn't be don't but there may be a way forward

The problem was that I was only setting the Value property of the RadComboBox and not the Text property. Even though text value was showing in the RadComboBox in edit mode apparently it was displaying the Value property. As soon as it was set it started posting back just like it was supposed to do.
if (!(e.Item.DataItem is GridInsertionObject))
{
_participantList.SelectedValue =
((ReinsuranceAgreementParticipant) (e.Item.DataItem)).LegacyReinsurerID.ToString();
// I added this line
_participantList.Text = ((ReinsuranceAgreementParticipant)(e.Item.DataItem)).LegacyReinsurerID.ToString();
}
if (e.Item.DataItem is GridInsertionObject)
_participantList.EmptyMessage = "Select Reinsurer";

Related

C# Binding Source Control

I am Developing a winforms application. I have two datagrid views populated from two different bindingsources(control). I am using these to implement the master detail approach. My problem is that when the first datagridview is populated using the binding source I can't select the first row of it ,because the first element in the binding source is defaultly selected and can't be selected. Can any one provide me a solution for this
As you say the first row is selected by default. So after populating the DataSource to your first GridView you can set the second GridView based on first entry. Later you check the selectionChanged Event to populate the second GridView based on selectedRow of your first one.
Code could look sth. like this:
private void PopulateDataSource()
{
dataGridView1.DataSource = myBindingSource;
DataRowView selectedRow;
if (dataGridView1.SelectedRows.Count > 0)
selectedRow = dataGridView1.SelectedRows[0] as DataRowView;
if (selectedRow != null)
dataGridView2.DataSource = myBindingSource2; //Set the BindingSource based on selectedRow in first Grid
}
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
DataRowView selectedRow;
if (dataGridView1.SelectedRows.Count > 0)
selectedRow = dataGridView1.SelectedRows[0] as DataRowView;
if (selectedRow != null)
dataGridView2.DataSource = myBindingSource2; //Set the BindingSource based on selectedRow in first Grid
}
If this doesn't work let me know but should do the job.
UDPATE
Here is a similar example using the events and methods of the bindingSource:
private void Initialize()
{
RegisterBindingSourceEvents();
dataGridView1.DataSource = bindingSource1;
dataGridView2.DataSource = bindingSource2;
bindingSource1.DataSource = myDataSource;
}
private void RegisterBindingSourceEvents()
{
bindingSource1.DataSourceChanged += BindingSource1_DataSourceChanged;
bindingSource1.CurrentChanged += BindingSource1_CurrentChanged;
}
private void BindingSource1_CurrentChanged(object sender, EventArgs e)
{
DataRowView row = bindingSource1.Current as DataRowView;
if (row != null)
bindingSource2.DataSource = myDataSource2BasedOnRow;
}
private void BindingSource1_DataSourceChanged(object sender, EventArgs e)
{
DataRowView row = bindingSource1.Current as DataRowView;
if (row != null)
bindingSource2.DataSource = myDataSource2BasedOnRow;
}
Further you maybe can use:
bindingSource.MoveNext();
bindingSource.MoveFirst();
To simulate focusing seconde row and directly first row. A bit ugly but i would guess this fires current_changed (untested). Better use first approach.
UDPATE-2
I'm sorry to tell you that this is not possible in a beautiful manner. The problem is that the Current Property of your bindingList is always set if your DataSource contains items. So if the user select the same row as the bindingSource Current Property contains your event won't get called. I found a solution which works in my example. You will need one gridEvent and maybe have to do some improvments but the idea should do the job. Sorry but without gridEvent i can't solve this:
Notice that iam using List as DataSource for my Testcase. You got DataTable and have to cast to DataRowView instead of Dummy for sure.
private bool _automatedRowChange;
private void Initialize()
{
List<Dummy> dummies = new List<Dummy> { new Dummy { Id = 1, Text = "Test1" }, new Dummy { Id = 2, Text = "Test2" } };
bindingSource1.DataSource = dummies;
dataGridView1.DataSource = bindingSource1;
//So the first row isn't focused but the bindingSource Current Property still holds the first entry
//That's why it won't fire currentChange even if you click the first row. Just looks better for the user i guess
dataGridView1.ClearSelection();
bindingSource1.CurrentChanged += BindingSource1_CurrentChanged;
dataGridView1.CellClick += DataGridView1_CellClick;
}
private void DataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
var clickedRow = dataGridView1.Rows[e.RowIndex].DataBoundItem as Dummy;
var currentRow = bindingSource1.Current as Dummy;
if (clickedRow != null &&
currentRow != null &&
clickedRow.Equals(currentRow))
{
_automatedRowChange = true;
bindingSource1.MoveNext();
_automatedRowChange = false; //MovePrevious is based on the click and should load the dataSource2
bindingSource1.MovePrevious();
}
}
private void BindingSource1_CurrentChanged(object sender, EventArgs e)
{
if (!_automatedRowChange) //Check if you jump to next item automatically so you don't load dataSource2 in this case
{
//Set the second DataSource based on selectedRow
}
}

Adding ComboBox to Datagridview

I found a way to add a combobox to DataGridview (Winform) cell, but I have not found an event like ItemDataBound of DataGridView to set a value to comboBox. And do not know how to set a selected value of a comboBox to DataItem property of a current row (of a DataGridView) :(
Please give me some clues to do this task
Thanks you so much
You can use below method to add data to a combobox in gridview. If you dont have a list you can add items to the combobox as:
cmbdgv.Items.Add("Test");
private void bindDataToDataGridViewCombo() {
DataGridViewComboBoxColumn cmbdgv = new DataGridViewComboBoxColumn();
List<String> itemCodeList = new List<String>();
cmbdgv.DataSource = itemCodeList;
cmbdgv.HeaderText = "Test";
cmbdgv.Name = "Test";
cmbdgv.Width = 270;
cmbdgv.Columns.Add(dgvCmbForums);
cmbdgv.Columns["Test"].DisplayIndex = 0;
}
After adding if you want to capture the combobox selection change you can use below event in the datagridview.
ComboBox cbm;
DataGridViewCell currentCell;
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if (e.Control is ComboBox)
{
cbm = (ComboBox)e.Control;
if (cbm != null)
{
cbm.SelectedIndexChanged += new EventHandler(cbm_SelectedIndexChanged);
}
currentCell = this.dataGridView1.CurrentCell;
}
}
void cbm_SelectedIndexChanged(object sender, EventArgs e)
{
this.BeginInvoke(new MethodInvoker(EndEdit));
}
void EndEdit()
{
if (cbm != null)
{
string SelectedItem=cbm.SelectedItem.ToString();
int i = dataGridView1.CurrentRow.Index;
dataGridView1.Rows[i].Cells["Test"].Value = SelectedItem;
}
}
If you are trying to set the value to a Combobox in a DataGridView, see if this answer will help.
To get the selected item of the Combobox (example):
comboBox.SelectedIndexChanged += new EventHandler(comboBox_ComboSelectionChanged);
private void comboBox_ComboSelectionChanged(object sender, EventArgs e)
{
if (myDGV.CurrentCell.ColumnIndex == 5)
{
int selectedIndex;
string selectedItem;
selectedIndex = ((ComboBox)sender).SelectedIndex; // handle an error here.
// get the selected item from the combobox
var combo = sender as ComboBox;
if (selectedIndex == -1)
{
MessageBox.Show("No value has been selected");
}
else
{
// note that SelectedItem may be null
selectedItem = combo.SelectedItem.ToString();
if (selectedItem != null)
{
// Your code

Event handler not firing on dynamic button click

I have a dynamically created button with an onclick event handler. The problem is that when I click the button it does not hit the event in the code-behind.
protected void gvOrder_RowDataBound(object sender, GridViewRowEventArgs e)
{
DataTable dt = ds.Tables[0];
DropDownList ddl = new DropDownList();
TextBox txt = new TextBox();
int index = 1;
if (e.Row.RowType == DataControlRowType.DataRow)
{
ddl = e.Row.FindControl("ddlNewO") as DropDownList;
txt = e.Row.FindControl("txtNewT") as TextBox;
}
foreach (DataRow r in dt.Rows)
{
string listitem = Convert.ToString(index);
ddl.Items.Add(listitem);
index++;
}
ddl.SelectedIndex = e.Row.RowIndex;
if (e.Row.RowIndex == 0)
{
ddl.Enabled = false;
txt.Enabled = false;
}
else if (e.Row.RowIndex != 0)
{
ddl.Items.Remove("1");
//Create ED button
if (e.Row.RowType == DataControlRowType.DataRow)
{
Button btnED = new Button();
btnED.ID = "btnED";
btnED.CssClass = "buttonsmall";
//btnED.CommandName = "ED";
btnED.EnableViewState = true;
btnED.Click += new EventHandler(btnED_Click);
foreach (DataRow r in dt.Rows)
{
btnED.Attributes.Add("ID", r.ItemArray[2].ToString());
if (r.ItemArray[3].ToString() == "1")
{
btnED.Text = "Disable";
}
else
{
btnED.Text = "Enable";
}
//Add button to grid
e.Row.Cells[5].Controls.Add(btnED);
}
}
}
}
protected void btnED_Click(object sender, EventArgs e)
{
// Coding to click event
}
So the problem here is that when the page is being recreated on post back - there is no more button! Dynamic controls need to be added on the page on every post back to fire events properly. In your case however on the first load when the GridView is binding you add the button to the page. But on the post back after the click the button is not added again, because GridView is not data bound again. Therefore ASP.NET cannot derive the source of the event, and supresses it.
Fix here is to bind GridView with data on every post back. Literally if you had if (!IsPostBack) - remove it. Or you can add the button in the template field and play with visibility - may be an approach as well.
You need to add a click handler on Row Created not on Data Bound I believe.
protected void gvOrderRowCreated(object sender, GridViewRowEventArgs e)
{
switch (e.Row.RowType) {
case DataControlRowType.DataRow:
Button btn = (Button)e.Row.FindControl("btnED");
btn.Command += btnED_Click;
break;
}
}

How to make DropDownList automatically be selected based on the Label.Text

I have a DropDownlist in the GridView, which should be visible only when edit is clicked. I have bound the DropDownList from code behind. When I click on Edit, the label value of that cell should automatically get selected in the DropDownList.
The code I have tried is:
protected void GridView3_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
SqlCommand cmd = new SqlCommand("SELECT Location_Name FROM Location_Table");
DropDownList bind_drop = (e.Row.FindControl("DropList") as DropDownList);
bind_drop.DataSource = this.ExecuteQuery(cmd, "SELECT");
bind_drop.DataTextField = "Location_Name";
bind_drop.DataValueField = "Location_Name";
bind_drop.DataBind();
string Loc_type = (e.Row.FindControl("id2") as Label).Text.Trim();
bind_drop.Items.FindByValue(Loc_type).Selected = true;
}
}
When I run the code, it gives an exception error Object reference not set in the last line of the above code.
Cannot find out whats wrong. Kindly help
You must ensure that your list contains label value.
var index = DropDownList1.Items.IndexOf(Loc_type );
if(index > 0)
{
DropDownList1.SelectedIndex = index;
}
else
{
Console.WriteLine("item does not exist");
}

Index Change event for Combobox of gridtemplateColumn in Telerik

I can write a code.
In this I can take a Template Column & in this I build a RadCombobox.
When it's Index changed I want to affect the below text box.
Link the selected value of the Combo box is set as Text on Below TextBox.
Combo Box & Text Box are different Controls of Different Template Column.
I can Write Control of Combo box like this :
<telerik:RadComboBox ID="cmbGID" runat="server" DataSourceID="SqlDataSource8" DataTextField="Name"
DataValueField="ID" AutoPostBack="True" OnSelectedIndexChanged="cmbGID_SelectedIndexChanged">
But I don't know the parameters of this event like this :
protected void cmbGID_SelectedIndexChanged()
{
//code...
}
Any one plz tell me that parameters & tell me is that possible to set txtValue.Text = cmbGID.SelectedValue.ToString()...???
I got the solution of this problem...
This is working by following code :
protected void cmbGrp_SelectedIndexChanged(object sender, RadComboBoxSelectedIndexChangedEventArgs e)
{
RadComboBox ddlCtrl = sender as RadComboBox;
GridEditableItem dataItem = ddlCtrl.NamingContainer as GridEditableItem;
RadComboBox cmbCtrl = dataItem.FindControl("cmbSetNo") as RadComboBox;
RadTextBox txtCtrl = dataItem.FindControl("cmbSetNo") as RadTextBox;
txtCtrl.Text = ddlctrl.SelectedValue.ToString();
string query = "QUERY";
ds.Clear();
ds = c.getDataSet(query);
cmbCtrl.DataSource = ds.Tables[0];
cmbCtrl.DataTextField = "NO";
cmbCtrl.DataValueField = "RecordID";
cmbCtrl.DataBind();
}
Something like this should work:
protected void vmbGID_SelectedIndexChanged(object sender, EventArgs e)
{
var ddlCtrl = sender as RadComboBox;
if (ddlCtrl != null)
{
var dataItem = ddlCtrl.Parent as GridDataItem;
if (dataItem != null)
{
var txtCtrl = dataItem.FindControl("txtValue") as RadTextBox;
if (txtCtrl != null)
{
txtCtrl.Text = ddlCtrl.SelectedValue;
}
}
}
}

Categories

Resources