I want to see whatever I see in my comboboxcell in other cell only for the current row I'm trying something like this with no result:
dataGridView1.Rows[0].Cells[0].Value =
dataGridView1.Rows[0].Cells[1].Value;\\ cell 1 is my comboboxcell
I have a class named with Item to add items in List,
Item class;
public class Item
{
public string Name { get; set; }
public int Id { get; set; }
}
In Form_Load, I loaded datagridview,
private void Form1_Load(object sender, EventArgs e)
{
dataGridView1.Columns.Add("test1", "test1");
DataGridViewComboBoxColumn testCol = new DataGridViewComboBoxColumn();
testCol.HeaderText = "comboValues";
dataGridView1.Columns.Add(testCol);
dataGridView1.Columns.Add("test2", "test1");
List<Item> items = new List<Item>();
items.Add(new Item() { Name = "One", Id = 1 });
items.Add(new Item() { Name = "Two", Id = 2 }); // created two Items
var cbo = dataGridView1.Columns[1] as DataGridViewComboBoxColumn; // index of 1 is the comboboxColumn
cbo.DataSource = items; // setting datasource
cbo.ValueMember = "Id";
cbo.DisplayMember = "Name";
dataGridView1.Rows.Add("", items[1].Id, "test1");
dataGridView1.Rows.Add("", items[0].Id, "test2");
dataGridView1.Rows.Add("", items[1].Id, "test3"); // and test rows
}
We need to check which row is the previous one before new selection, so we need to use Row_Leave event.
int previousRowIndex = 0; // a variable to keep the index of row
private void dataGridView1_RowLeave(object sender, DataGridViewCellEventArgs e)
{
previousRowIndex = e.RowIndex;
}
And the main event is SelectionChanged,
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
dataGridView1.Rows[previousRowIndex].Cells[0].Value = ""; // first set the previous row's first cell value empty string.
DataGridViewComboBoxCell comboCell = dataGridView1.CurrentRow.Cells[1] as DataGridViewComboBoxCell;
dataGridView1.CurrentRow.Cells[0].Value = comboCell.EditedFormattedValue; // then set the first cell's value as the combobox's selected value.
}
Result;
Hope helps,
Related
I have filled listBox with data and assigning it to gridview but it doesn't. I verified by setting count of list to variable and it shows 3, perfect but after assigning it to gridview, the count of gridview shows 0. Why ?
protected void btnShowTempFeatures_Click(object sender, EventArgs e)
{
try
{
int count = ListBoxFeatures.Items.Count; //returns 3
grdViewTemporaryFeatures.DataSource = ListBoxFeatures.DataSource;
grdViewTemporaryFeatures.DataBind();
int CountGrid= grdViewTemporaryFeatures.Rows.Count; //return 0
}
}
Solved
protected void btnShowTempFeatures_Click(object sender, EventArgs e)
{
try
{
int count = ListBoxFeatures.Items.Count;
//grdViewTemporaryFeatures.DataSource = ListBoxFeatures.DataSource;
//grdViewTemporaryFeatures.DataBind();
int CountGrid= grdViewTemporaryFeatures.Rows.Count;
ListItemCollection lstTempFeatures = ListBoxFeatures.Items;
DataTable dTempFeatures = new DataTable();
dTempFeatures.Columns.Add("ID");
dTempFeatures.Columns.Add("FeatureName");
foreach (ListItem lstItem in lstTempFeatures)
{
DataRow dr = dTempFeatures.NewRow();
dr["ID"]= lstItem.Value;
dr["FeatureName"] = lstItem.Text;
dTempFeatures.Rows.Add(dr);
}
grdViewTemporaryFeatures.DataSource = dTempFeatures;
grdViewTemporaryFeatures.DataBind();
mdlTemporaryFeatures.Show();
}
I created a dynamic combobox in my DataGridview like this:
string strcmd2 = "Select Food_Name,Food_ID from dbo.TblFood_Food ";
Dt2 = Dbc.seletcmd(strcmd2);
DataGridViewComboBoxColumn ColumnAcc = new DataGridViewComboBoxColumn();
ColumnAcc.DataPropertyName = "combo";
ColumnAcc.HeaderText = "Food";
ColumnAcc.DataSource = Dt2;
ColumnAcc.DisplayMember = "Food_Name";
ColumnAcc.ValueMember = "Food_ID";
DataGridview_Food.Columns.Insert(0,ColumnAcc);
Now I want when user selected an item in combobox, its value emerge in another cell of datagridview. what can i do?
Thanks
try this....
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace App1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
//string strcmd2 = "Select Food_Name,Food_ID from dbo.TblFood_Food ";
//Dt2 = Dbc.seletcmd(strcmd2);
//fabricate some data....
List<Food> Foods = new List<Food>();
Foods.Add(new Food() { Food_ID = "0", Food_Name = "NONE" });
Foods.Add(new Food() { Food_ID = "1", Food_Name = "Burger" });
Foods.Add(new Food() { Food_ID = "2", Food_Name = "Fries" });
DataGridViewComboBoxColumn ColumnAcc = new DataGridViewComboBoxColumn();
ColumnAcc.DataPropertyName = "combo";
ColumnAcc.HeaderText = "Food";
ColumnAcc.Name = "Food";
ColumnAcc.DataSource = Foods;
ColumnAcc.DisplayMember = "Food_Name";
ColumnAcc.ValueMember = "Food_ID";
DataGridview_Food.Columns.Insert(0, ColumnAcc);
DataGridview_Food.EditingControlShowing += DataGridview_Food_EditingControlShowing;
}
private void DataGridview_Food_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if (((DataGridView)sender).CurrentCell.ColumnIndex == 0)
{
ComboBox cmb = e.Control as ComboBox;
if (cmb != null)
{
// remove the current event handler
cmb.SelectionChangeCommitted -= new EventHandler(cmb_SelectionChanged);
// now re-attach the event handler
cmb.SelectionChangeCommitted += new EventHandler(cmb_SelectionChanged);
}
}
}
private void cmb_SelectionChanged(object sender, EventArgs e)
{
ComboBox cmb = (ComboBox)sender;
Food selectedFood = (Food)cmb.SelectedItem;
MessageBox.Show(string.Format("You selected item {0} ---> {1}", selectedFood.Food_ID, selectedFood.Food_Name));
}
}
}
class Food
{
public string Food_Name { get; set; }
public string Food_ID { get; set; }
}
One option is to handle the DataGridView.CellEndEdit event. After you select an option from the ComboBox and leave the cell, have it update the desired cell. Let's assume the ComboBox column is indexed at 0 and the desired column to update is column 1:
this.dataGridView1.CellEndEdit += DataGridView1_CellEndEdit;
private void DataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == 0)
{
this.dataGridView1[1, e.RowIndex].Value = this.dataGridView1[e.ColumnIndex, e.RowIndex].Value;
}
}
Now let's imagine you have the following ComboBox items:
{{ Food_Name = "Apple", Food_ID = 1 },
{ Food_Name = "Steak", Food_ID = 2 },
{ Food_Name = "Toast", Food_ID = 3 }}
Having set the ComboBoxColumn.ValueMember = "Food_ID: Choosing Apple will set the other cell value to 1; choosing Steak sets the other cell value to 2; etc. That said, if Food_ID is not the value you want to set in the other cell, then consider Monty's approach using the EditControlShowing event.
I have a DataGridView with a ComboBox column.
The ComboBox gets filled with a specific list of names and they are identical for every row in the DataGridView.
After I fill my DataGridView, I would like to do the following:
I want every Combo’s value to be set to the corresponding row’s “Table Columns” value, if exists.
I.e. in the picture above I want the value of the first Combo to be “id” (if it contains an item named “id”), the second to be “firstname”, etc.
If the value is not found, it should not select any value in the ComboBox.
Update: My current code that is not working
private void Mappings_Load(object sender, EventArgs e)
{
dgv.DataSource = tableColumns.Select(x => new { Value = x }).ToList();
dgv.Columns[0].HeaderText = "Table Columns";
DataGridViewComboBoxColumn comboColumn = new DataGridViewComboBoxColumn();
comboColumn.HeaderText = "File Columns";
foreach (var item in fileColumns)
comboColumn.Items.Add(item);
dgv.Columns.Add(comboColumn);
foreach(DataGridViewRow row in dgv.Rows)
{
string tableColumnValue = row.Cells[0].Value.ToString();
row.Cells[0].Value = tableColumnValue;
}
}
Trace the change .. you almost did it
private void Form1_Load(object sender, EventArgs e)
{
string[] tableColumns = new string[] { "A", "B", "C", "D" };
string[] fileColumns = new string[] { "A", "B", "C", "X" };
dgv.DataSource = tableColumns.Select(x => new { Value = x }).ToList();
dgv.Columns[0].HeaderText = "Table Columns";
DataGridViewComboBoxColumn comboColumn = new DataGridViewComboBoxColumn();
comboColumn.HeaderText = "File Columns";
foreach (var item in fileColumns)
comboColumn.Items.Add(item);
dgv.Columns.Add(comboColumn);
foreach (DataGridViewRow row in dgv.Rows)
{
string tableColumnValue = row.Cells[0].Value.ToString();
//Change is here
if (fileColumns.Any(i => i == tableColumnValue))
{
row.Cells[1].Value = tableColumnValue;
}
//end change
}
}
A while ago I did a similar thing:
Recognize which fields are of type enum
For the fiels of type enum, show a ComboBoxin the cell of the DataGridView (containing all the possible values of the enum) instead of the simple text field.
I think you only need to change certain parts of the code to transform it to what you are trying to achieve:
public partial class TableView<CollectionType, ItemType> : Form
{
public TableView(CollectionType elements)
{
InitializeComponent();
// custom:
this.DataGridView.DataSource = elements;
AdaptColumnsToColumnValueType();
}
private void AdaptColumnsToColumnValueType()
{
for (int columnIndex = 0; columnIndex < this.DataGridView.Columns.Count; columnIndex++)
{
var column = (DataGridViewColumn)this.DataGridView.Columns[columnIndex];
if (column.ValueType.IsEnum)
{
ReplaceColumnInDatagridView(
oldColumn: column,
newColumn: CreateComboBoxWithEnums(column));
}
}
}
private void ReplaceColumnInDatagridView(DataGridViewColumn oldColumn, DataGridViewColumn newColumn)
{
int columnIndex = oldColumn.Index;
this.DataGridView.Columns.Remove(oldColumn);
this.DataGridView.Columns.Insert(columnIndex, newColumn);
}
private DataGridViewComboBoxColumn CreateComboBoxWithEnums(DataGridViewColumn replacedEnumColumn)
{
var comboboxColumn = new DataGridViewComboBoxColumn();
comboboxColumn.DataSource = Enum.GetValues(replacedEnumColumn.ValueType);
comboboxColumn.DataPropertyName = replacedEnumColumn.DataPropertyName;
comboboxColumn.Name = replacedEnumColumn.Name;
return comboboxColumn;
}
}
you can use the DataGridViews RowsAdded event.
Edit: cmb is your ComboBoxColumn
private void dataGridView1_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e) {
//Check if comboboxcolumn contains the value
if(cmb.Items.Contains(dataGridView1.Rows[e.RowIndex].Cells[0].Value)) {
//Set the value
dataGridView1.Rows[e.RowIndex].Cells["cmb"].Value = dataGridView1.Rows[e.RowIndex].Cells[0].Value;
}
}
I am a beginner of C# and created a DataGridView like:
private DataGridViewTextBoxColumn createText(string name, string Hname, int width)
{
DataGridViewTextBoxColumn tmt = new DataGridViewTextBoxColumn();
tmt.Name = name;
tmt.HeaderText = Hname;
tmt.Width = width;
tmt.DataPropertyName = name;
return tmt;
}
private DataGridViewComboBoxColumn PMcreateCombo(string name, int width, string item_str)
{
DataGridViewComboBoxColumn tmd = new DataGridViewComboBoxColumn();
string[] items;
items = item_str.Split(' ');
tmd.HeaderText = name;
tmd.Name = name;
//tmd.MaxDropDownItems = 4;
foreach (string str in items)
{
tmd.Items.Add(str);
}
tmd.Width = width;
tmd.DataPropertyName = name;
return tmd;
}
I want to use a numericupdown to control the number of columns, so i wrote something like this:
private void numericUD_ValueChanged(object sender, EventArgs e)
{
Dgv.DataSource = null;
Dgv.Rows.Clear();
Init();
}
private void Init()
{
SCM = new List<SCM>();
Dgv.AutoGenerateColumns = false;
Dgv.AllowUserToAddRows = false;
Dgv.Columns.Add(createText("AA", "AA", 60));
Dgv.Columns.Add(createCombo("QQ", 60, "RRR GGG BBB"));
addNewColumns();
Dgv.DataSource = Table;
}
But when i change the numericUpDown, the AA QQ and Addnewcolumn all are created just after the old one, but if i mark the Init() in the functionnumericUD_ValueChanged, the first row (AA QQ) still remains, but the second row disappears.
So i want to ask how to delete all of the element in DataGridView including the first row, then create a new one according to the numericrupdown
thanks
You need to refresh the DataGridView after clearing the datasource.
private void numericUD_ValueChanged(object sender, EventArgs e)
{
Dgv.DataSource = null;
Dgv.refresh();
Init();
}
i have two list boxes in my form and a button in between these two boxes. In the first box i binded some data from the database and from this list box i have to select the items and should display those selected items in the second list box. this should happen when i click a button.i used the following code.i used a hash table.
private void btnCATAdd_Click(object sender, EventArgs e)
{
Hashtable ht = new Hashtable();
ht.Add(lbCATallSubcat.SelectedValue.ToString(),
lbCATallSubcat.Text.ToString());
int i = 0;
foreach (string ent in ht.Values)
{
string[] name = new string[lbCATallSubcat.Items.Count];
for (i = 0; i < lbCATallSubcat.SelectedItems.Count; i++)
{
name[i] = lbCATallSubcat.Text;
this.lbCATSelectedSubcat.Items.Add(name[i]);
}
lbCATSelectedSubcat.DisplayMember = ht.Values.ToString();
lbCATSelectedSubcat.ValueMember = ht.Keys.ToString();
}
}
well its working fine when im selecting only single item in the first list box but im unable to display when more than one item is selectd from the first list box
You should use SelectedItems property on that listbox instead SelectedValue. Currently your Hashtable contains only one element.
See http://msdn.microsoft.com/en-us/library/system.windows.forms.listbox.selecteditems.aspx
Add all selected value in hashtable using loop
private void btnCATAdd_Click(object sender, EventArgs e)
{
Hashtable ht = new Hashtable();
for(int i=0;i<lbCATallSubcat.Items.Count;i++)
{
if(ht.items[i].Selected)
{
ht.Add(lbCATallSubcat.Items[i].Value.ToString(),
lbCATallSubcat.Items[i].Text.ToString());
}
}
i = 0;
foreach (string ent in ht.Values)
{
string[] name = new string[lbCATallSubcat.Items.Count];
for (i = 0; i < lbCATallSubcat.SelectedItems.Count; i++)
{
name[i] = lbCATallSubcat.Text;
this.lbCATSelectedSubcat.Items.Add(name[i]);
}
lbCATSelectedSubcat.DisplayMember = ht.Values.ToString();
lbCATSelectedSubcat.ValueMember = ht.Keys.ToString();
}
}
Do you need the Hashtable? With LINQ, you can do something like:
public ObjHoldingData
{
public Display { get; set; }
public Value { get; set; }
}
public class Form
{
Form()
{
var dataList = new List<ObjHoldingData>();
//TODO: Fill list with all the data you pulled
Listbox1.Datasource = dataList;
Listbox1.DisplayMember = "Display";
Listbox1.ValueMember = "Value";
}
protected void ButtonClick()
{
Listbox2.Datasource = Listbox1.SelectedItems.Cast<ObjHoldingData>().ToList();
Listbox2.DisplayMember = "Display";
Listbox2.ValueMember = "Value";
}
}
If you still need the Hashtable you can do this at the start of the button click:
var ht = new Hashtable(ListBox1.SelectedItems.Cast<ObjHoldingData>().ToDictionary(o => o.Display, o => o.Value));