c1 TrueDBGrid cell value to textbox - c#

private void c1TrueDBGrid1_Click(object sender, EventArgs e)
{
}
How can I get the value of a cell and then display it in a textbox.
Just like this code that works for data grid view "OwnerIDtxtbox.Text = PetGrid.Rows[i].Cells[7].Value.ToString();"

c1TrueDBGrid exposes a couple of indexers that takes the row number as first parameter and the column name or index as the second - you can use either one of them.
Please note that both returns object.
var row = grid.Row; // get the current row
var columnIndex = 0;
var cellValue = grid[row, "ColumnName"];
var cellValue = grid[row, columnIndex];
Another option is to use
var value = grid.Columns[0].CellValue(row);
And of course, you can use the column's string indexer:
var value = grid.Columns["Company"].CellValue(row)
For more information, please refer to official documentation.

Related

DataGridViewComboBoxColumn Selected Value / Index

I am attempting to populate a DataGridViewComboBoxColumn with a list of strings then select one of them based upon their value on form load.
A simple task one would think, but I just can't get it right.
I am populating a DataGridViewComboBoxColumn with strings as such without a problem:
ComboBoxColumn.Items.AddRange("Mr.", "Ms.", "Mrs.", "Dr.");
I also seem to be able to add it to the DataGridView without a problem (This is incorrect see Edit):
ExampleDataGrid.Rows.Add("", ComboBoxColumn, 1000, "");
Now I want to set "Mr." to be selected on load. Other posts suggest that I should be able to simply use:
ExampleDataGrid.Rows[i].Cells["ExampleColumnName"].Value = "Mr.";
But whenever I use it, I get an error that tells me the value is not valid.
Is there something I'm missing?
I can however use this to get the set value without issue:
string Title = ExampleDataGrid.Rows[i].Cells["ExampleColumnName"].Value;
I had a look at the documentation but it doesn't seem to mention how to actually use .Value in this context.
Microsoft Docs
Any thoughts on where I am going wrong would be great.
Edit:
The issue I was having was caused by me setting the ComboBoxItems in the
"ExampleDataGrid.Rows.Add()". This should actually contain the value you want to set. e.g.
ExampleDataGrid.Rows.Add("", "Mr.", 1000, "");
You can initialize the DataGridView this way:
private void Form1_Load(object sender, EventArgs e)
{
var textBoxColumn = new DataGridViewTextBoxColumn();
textBoxColumn.Name = "textBoxColumn";
var comboBoxColumn = new DataGridViewComboBoxColumn();
comboBoxColumn.Items.AddRange("A", "B", "C");
comboBoxColumn.Name = "comboBoxColumn";
dataGridView1.Columns.Add(textBoxColumn);
dataGridView1.Columns.Add(comboBoxColumn);
dataGridView1.Rows.Add("1", "A");
dataGridView1.Rows.Add("2", "B");
}
And then update the value of the comboBoxColumn for the second row this way:
private void button1_Click(object sender, EventArgs e)
{
//You can use either of the following ways:
dataGridView1[1, 1].Value = "C";
//dataGridView1["comboBoxColumn", 1].Value = "C";
//dataGridView1.Rows[1].Cells["comboBoxColumn"].Value = "C";
//dataGridView1.Rows[1].Cells[1].Value = "C";
}
The value which you set for the cell, should be between the values which you added to Items of the DataGridViewComboBoxColumn.

How to determine a row index from a datatable that shares a column with a combobox

I have a combobox and a datatable.
I've added all of the elements of one column in the datatable to the combobox items.
Now whenever the user chooses a item in the combobox, I want to go to the datatable and compare the column, if there's a match, it will do some code.
I have the following
private void comboBox8_SelectedIndexChanged(object sender, EventArgs e)
{
string str = comboBox8.SelectedItem.ToString();
int z = 0;
foreach (var row in datatable.Rows)
{
int i = 0; i++;
if (datatable.Rows[row]["Cidade"] == str)
{
z = i;
}
}
}
"Cidade" is the column name that matches the options in the combobox.
The Problem is that the code doesn't identify the ìf` condition as valid, saying there are invalid arguments
Edit: worked it around like this:
private void comboBox8_SelectedIndexChanged(object sender, EventArgs e)
{
string str = comboBox8.SelectedItem.ToString();
int z = 0;
for (int i = 0; i < DataAccess.Instance.tabelasismica.Rows.Count; i++)
{
if (DataAccess.Instance.tabelasismica.Rows[i]["Cidade"] == str)
{
z = i;
}
}
MessageBox.Show(z.ToString());
MessageBox.Show(DataAccess.Instance.tabelasismica.Rows[z]["Cidade"].ToString());
}
Standard way of doing things like this is to use data-binding. You'd simply set your ComboBox's DataSource to your DataTable. The code would roughly look like this:
comboBox8.DataSource = datatable;
comboBox8.DisplayMember = "Cidade"
comboBox8.ValueMember = "PrimaryKeyColumnOfYourTable"
Now in the SelectedIndexChanged event, you simply use comboBox8.SelectedValue property to get the ID of the selected row. If you have strongly typed DataSet, your DataTable will have a function named FindByYourPKColumn() that you can use to find the row using this ID.
datatable.Rows[row]["Cidade"] is of type object - you need to convert it to a string before comparing it to str, like this:
if (datatable.Rows[row]["Cidade"].ToString() == str)
{ ... }
Try this in place of the for loop
foreach (DataRow row in dDataAccess.Instance.tabelasismica.Rows)
{
if (row["Cidade"].ToString() == str)
{
z = dDataAccess.Instance.tabelasismica.Rows.IndexOf(row);
}
}
or
foreach (DataRow row in dataTable.Rows)
{
if (row["Cidade"].ToString() == str)
{
z = dataTable.Rows.IndexOf(row);;
}
}
Being said that, standard practice in using ComboBoxes, ListBoxes etc with datasources is to to have a distinct column in the data-table assigned as the ValueMember of the ComboBox, which makes life even easier - as suggested by #dotNET.
comboBox8.DataSource= dataTable; //the data table which contains data
comboBox8.ValueMember = "id"; // column name which you want in SelectedValue
comboBox8.DisplayMember = "name"; // column name that you need to display as text
That way you don't have to iterate through the dataTable to find the index of the row, and you can use the ID (ValueMember) to continue process as required.
Example here
#dotNET's answer is the preferred method to solve your specific problem.
However to solve the general problem find a value in a dataset your best bets are to either
Use the ADO.NET methods Find or Select e.g.
var results = dataset.Select(string.Format("Cidade = {0}",str));
if (results.Count() != 0 )
{
...
}
Or use System.Data.DataSetExtensions
if (datatable.AsEnumerable().Any( x=> x.Field<string>("Cidade") == str ))
{
....
}

Total cell count of a DataGridView

I need to get the total number of cells that are present in a datagridview. This is then used to determine if I want to include the column header text when copying/pasting the data, I only want this displayed if all records are selected.
I am using the following code to get the total number of cells but is there a better way to get this value?
var totalCellCount = DataGridView2.ColumnCount * DataGridView2.RowCount;
I couldn't find a property that contained a count of all cells, maybe I am missing it. Is there a better way to get the number of cells?
My datagridview has the ClipboardCopyMode set to EnableWithAutoHeaderText, but I want to set it to EnableAlwaysIncludeHeaderText when they select all rows/columns in the grid. So I am using the total number of cells in the code below:
private void DataGridView_KeyPress(object sender, KeyPressEventArgs e)
{
if (m_RecordCount == 0)
return;
var totalCellCount = DataGridView2.ColumnCount * DataGridView2.RowCount;
if (DataGridView2.SelectedCells.Count == totalCellCount)
{
if (e.KeyChar == (char)3)
{
DataGridView2.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText;
var clipboardContent = this.DataGridView2.GetClipboardContent();
if (clipboardContent != null)
{
Clipboard.SetText(clipboardContent.GetText(TextDataFormat.Text));
}
e.Handled = true;
}
}
}
The DataGrid.Items property returns a DataGridItemCollection representing the DataGridItems in the DataGrid.
Each DataGridItem is representative of a single row in the rendered table. Also, the DataGridItem exposes a Cells property which represents the no. of tablecells (in other words, the columns) in the rendered table. From here if you need any other custom scenarios you will have to either add it to the original Question or code a solution
var rowCount = DataGridView2.Items.Count; //Number of Items...i.e. Rows;
// Get the no. of columns in the first row.
var colCount = DataGridView2.Items[0].Cells.Count;
if you want the total number of Rows also try
If you want to get at total items an you want a real total for example if you have multiple pages.. If so you shouldn't be trying to find that information from the GridView but instead look at the underlying DataSource that you bound your GridView.
Example ----
List<SomeObject> lis = GetYourData();
DataGrid.DataSource = list;
DataGrid.DataBind();
// if you want to get the count for a specific page
int currentPage = 2;
int countForPage2 = (list.Count > currentPage * totalItemsPerPage)) ?
totalItemsPerPage : list.Count - ((currentPage - 1) * totalItemsPerPage);

Select value and text both from DataGridViewComboBoxColumn c#

suppose i have one datagridview and datagridview has one DataGridViewComboBoxColumn.
i have populate datagridview combobox column with country name and code.
so now i want that when i am reading datagridview cell value in for loop then i want get DataGridViewComboBoxColumn selected value and text. i could not get the value but not being able to get display text from DataGridViewComboBoxColumn in for loop.
if it is possible then plzz help me with small code.
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i <= dgList.Rows.Count - 1; i++)
{
DataGridViewComboBoxCell cell = dgList.Rows[i].Cells[0] as DataGridViewComboBoxCell;
int index = cell == null || cell.Value == null ? -1 : cell.Items.IndexOf(cell.Value);
string strVal = cell.Value.ToString();
}
}
thanks
Can you try accessing the values like FormattedValue and Value, this should give you the two values.
I had tried using a Dictionary<string,string> as DataSource and using the above properties i was able to get both the values.
Try This:
for (int i = 0; i <= dgList.Rows.Count - 1; i++)
{
string strval=((ComboBox)(dgList.Rows[i].cells[0].FindControl("ComboBox1"))).SelectedValue;
}
Cant you just cast the value to the expected type?
Try this:
dgList["columnName", RowIndex].Value
For example
Convert.toInt32(dgList["columnName", RowIndex].Value)

DatagGridViewColumn.DataPropertyName to an array element?

I'm using a DataGridView binding its datasource to a List, and specifying the properties for each column.
An example would be:
DataGridViewTextBoxColumn colConcept = new DataGridViewTextBoxColumn();
DataGridViewCell cell4 = new DataGridViewTextBoxCell();
colConcept.CellTemplate = cell4;
colConcept.Name = "concept";
colConcept.HeaderText = "Concept";
colConcept.DataPropertyName = "Concept";
colConcept.Width = 200;
this.dataGridViewBills.Columns.Add(colConcept);
{... assign other colums...}
And finally
this.dataGridViewBills.DataSource=billslist; //billslist is List<Bill>
Obviously Class Bill has a Property called Concept, as well as one Property for each column.
Well, now my problem, is that Bill should have and Array/List/whateverdynamicsizecontainer of strings called Years.
Let's assume that every Bill will have the same Years.Count, but this only known at runtime.Thus, I can't specify properties like Bill.FirstYear to obtain Bill.Years[0], Bill.SecondYear to obtain Bills.Years[1]... etc... and bind it to each column.
The idea, is that now I want to have a grid with dynamic number of colums (known at runtime), and each column filled with a string from the Bill.Years List. I can make a loop to add columns to the grid at runtime depending of Bill.Years.Count, but is possible to bind them to each of the strings that the Bill.Years List contains???
I'm not sure if I'm clear enough.
The result ideally would be something like this, for 2 bills on the list, and 3 years for each bill:
--------------------------------------GRID HEADER-------------------------------
NAME CONCEPT YEAR1 YEAR2 YEAR3
--------------------------------------GRID VALUES-------------------------------
Bill1 Bill1.Concept Bill1.Years[0] Bill1.Years[1] Bill1.Years[2]
Bill2 Bill2.Concept Bill2.Years[0] Bill2.Years[1] Bill2.Years[2]
I can always forget the datasource, and write each cell manually, as the MSFlexGrid used to like, but if possible, I would like to use the binding capabilities of the DataGridView.
Any ideas? Thanks a lot.
I recently ran into this same problem. I ended up using DataGridView's virtual mode instead of binding to a data source. It doesn't have exactly the same features as binding, but it's still a lot more powerful than populating each cell manually.
In virtual mode, the DataGridView will fire an event whenever it needs to display a cell, which essentially means you can populate the cell however you please:
private void my_init_function() {
datagridview.VirtualMode = true;
datagridview.CellValueNeeded += new System.Windows.Forms.DataGridViewCellValueEventHandler(datagridview_CellValueNeeded);
}
private void datagridview_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
{
e.Value = get_my_data(e.RowIndex, e.ColumnIndex);
}
You could use reflection to set up and fill the DataGridView. I've done this with a single type, but I don't see why it couldn't be extended to your data structure.
To set up the DataGridView:
// Create the columns based on the data in the album info - get by reflection
var ai = new AlbumInfo();
Type t = ai.GetType();
dataTable.TableName = t.Name;
foreach (PropertyInfo p in t.GetProperties())
{
// IF TYPE IS AN ARRAY (OR LIST) THEN ADD A COLUMN FOR EACH ELEMENT
var columnSpec = new DataColumn();
// If nullable get the underlying type
Type propertyType = p.PropertyType;
if (IsNullableType(propertyType))
{
var nc = new NullableConverter(propertyType);
propertyType = nc.UnderlyingType;
}
columnSpec.DataType = propertyType;
columnSpec.ColumnName = p.Name;
dataTable.Columns.Add(columnSpec);
}
dataGridView.DataSource = dataTable;
Then to populate the DataGridView:
// Add album info to table - add by reflection
var ai = new AlbumInfo();
Type t = ai.GetType();
// WOULD NEED TO INCREASE BY LENGTH OF ARRAY
var row = new object[t.GetProperties().Length];
int index = 0;
foreach (PropertyInfo p in t.GetProperties())
{
// IF TYPE IS AN ARRAY (OR LIST) THEN ADD EACH ELEMENT
row[index++] = p.GetValue(info, null);
}
dataTable.Rows.Add(row);
This is just the code I used, so you'll have to modify the code to handle your year array/list.

Categories