Fill DataGridView from checkedListBox - c#

I have a checkedListBox1 and i want to convert all it's items to a DataGridView
i have the following code
string[] ar = new string[60];
for (int j = 0; j < checkedListBox1.Items.Count; j++)
{
ar[j] = checkedListBox1.Items[j].ToString();
}
dataGridView2.DataSource = ar;
but the dataGridView2 is filled with the length of the item instead of the item itself, can any one help?

These code blocks may give an idea (all is worked for me). CheckedListBox items returns a collection. It is coming from IList interface so if we use a List item as datasource for datagridview solves the problem. I used genericList as an additional class of Sample. When we use string array datagridview shows each items length. In here overried ToString returns original value.
class Sample
{
public string Value { get; set; }
public override string ToString()
{
return Value;
}
}
In form class:
private void button1_Click(object sender, EventArgs e)
{
CheckedListBox.ObjectCollection col = chk.Items;
List<Sample> list = new List<Sample>();
foreach (var item in col)
{
list.Add(new Sample { Value = item.ToString() });
}
dgw.DataSource = list;
}

This simple DataTable code appears to work...
DataTable dt = new DataTable();
dt.Columns.Add("Name", typeof(string));
for (int j = 0; j < checkedListBox1.Items.Count; j++) {
dt.Rows.Add(checkedListBox1.Items[j].ToString());
}
dataGridView1.DataSource = dt;

Because DataGridView looks for properties of containing objects. For string there is just one property - length. So, you need a wrapper for a string like this.
string[] ar = new string[60];
for (int j = 0; j < checkedListBox1.Items.Count; j++)
{
ar[j] = checkedListBox1.Items[j].ToString();
}
dataGridView1.DataSource = ar.Select(x => new { Value = x }).ToList();

Related

WPF datagrid row header binding - Observable collection

I have built a datagrid using datatable and the results are displayed correctly.
Now I intend to add ROWHEADERs to the datagrid. I populated an observable collection<string>and in the XAML, I use that as row header data template path. Still, it is not showing up. Can somebody advice where the issue is?
public ObservableCollection<string> Rownameheaders { get; set; } //in the main .cs
//xaml.cs
public void Form1_load(object sender, EventArgs e)
{
WF_CRM_RPluginModel model = DataContext as WF_CRM_RPluginModel;
var hello1 = new ObservableCollection<String>();
for(int i=0; i< model.prodwells.Count;i++)
{
hello1.Add(model.prodwells[i]);
}
model.Rownameheaders = hello1;
List<double[]> list = new List<double[]>();
for (int i = 0; i < model.RowFijtable; i++)
{
double[] rowdata = new double[model.ColFijtable];
for (int j = 0; j < model.ColFijtable; j++)
{
rowdata[j] = model.TauTable[i, j];
}
list.Add(rowdata);
}
DataTable table = ConvertListToDataTable(list);
dataGridView1.ItemsSource = table.AsDataView();
}
private DataTable ConvertListToDataTable(List<double[]> list)
{
DataTable table = new DataTable();
WF_CRM_RPluginModel model = DataContext as WF_CRM_RPluginModel;
// Get max columns.
int columns = 0;
foreach (var array in list)
{
if (array.Length > columns)
{
columns = array.Length;
}
}
// Add columns.
for (int i = 0; i < columns; i++)
{
// Provide default column name & data type
table.Columns.Add(model.injwells[i], typeof(double));
}
// Add rows.
foreach (var array in list)
{
// assign each array element to the appropriate column
var row = table.NewRow();
for (int i = 0; i < array.Length; ++i)
row.SetField(i, array[i]);
table.Rows.Add(row);
}
return table;
}
XAML:
<DataGrid Name="dataGridView1" Loaded="Form1_load" ItemsSource="{Binding}" AutoGenerateColumns="True" AlternatingRowBackground="Gainsboro" CanUserSortColumns="False">
<DataGrid.RowHeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGridRow}}, Path=Rownameheaders}"/>
</DataTemplate>
</DataGrid.RowHeaderTemplate>
</DataGrid>
This is the result I get but with no row headers...
I ended up adding a new column with values and setting the column location to 0 in the datatable. Below is the updated code:
private DataTable ConvertListToDataTable(List<double[]> list)
{
DataTable table = new DataTable();
WF_CRM_RPluginModel model = DataContext as WF_CRM_RPluginModel;
// Get max columns.
int columns = 0;
foreach (var array in list)
{
if (array.Length > columns)
{
columns = array.Length;
}
}
// Add columns.
for (int i = 0; i < columns; i++)
{
// Provide default column name & data type
table.Columns.Add(model.injwells[i], typeof(double));
}
// Add rows.
foreach (var array in list)
{
// assign each array element to the appropriate column
var row = table.NewRow();
for (int i = 0; i < array.Length; ++i)
row.SetField(i, array[i]);
table.Rows.Add(row);
}
//ADDED below part
DataColumn newCol = new DataColumn("Prod Name", typeof(string));
newCol.AllowDBNull = true;
table.Columns.Add(newCol);
newCol.SetOrdinal(0);
int m = 0;
foreach(DataRow row in table.Rows)
{
row["Prod Name"] = model.prodwells[m];
m = m + 1;
}
return table;
}
hope it helps others too!

Add List item checked values in grid view below existing rows

Hi I want to add my checkedboxList checked values inside grid view(Asp.net), below existing rows how can I do this. This is the code how I tried but that is not correctly adding
protected void CheckBoxList1_SelectedIndexChanged(object sender, EventArgs e)
{
// check view state is not null
if (ViewState["MailTracking"] != null)
{
//get datatable from view state
dt = (DataTable)ViewState["MailTracking"];
DataRow oItem = null;
if (dt.Rows.Count > 0)
{
for (int i = 1; i <= dt.Rows.Count; i++)
{
oItem = dt.NewRow();
string strValue = "";
for (int k = 0; k < CheckBoxListBranch.Items.Count; k++)
{
if (CheckBoxListBranch.Items[k].Selected)
{
strValue = CheckBoxListBranch.Items[k].Value;
oItem[0] = CheckBoxListBranch.Items[k].Text;
}
}
}
//Remove initial blank row
if (dt.Rows[0][0].ToString() == "")
{
dt.Rows[0].Delete();
dt.AcceptChanges();
}
dt.Rows.Add(oItem);
ViewState["MailTracking"] = dt;
GVDisplay.DataSource = dt;
GVDisplay.DataBind();
}
}
}
My asp:CheckBoxList ID is: CheckBoxListBranch I used onselectedindexchanged="CheckBoxList1_SelectedIndexChanged" inside asp:CheckBoxList.
I think you meant the below code statement
oItem[0] = CheckBoxListBranch.Items[k].Text;
to actually be, notice that it's oItem[k] else every time you are adding/re-ading the element to the first column of the row
oItem[k] = CheckBoxListBranch.Items[k].Text;
Per your comment: in that case you should move the code line dt.Rows.Add(oItem); inside your for loop as below
for (int k = 0; k < CheckBoxListBranch.Items.Count; k++)
{
if (CheckBoxListBranch.Items[k].Selected)
{
strValue = CheckBoxListBranch.Items[k].Value;
oItem[0] = CheckBoxListBranch.Items[k].Text;
dt.Rows.Add(oItem);
}
}

DataGridView with custom object inside each cell

In C# I have DataGridView and my custom class "Thing" that have override on toString() method.
All I want to do is to populate DataGridView with objects of a Thing type, and so the Thing objects can display them self on the DataGridView.
public class Thing
{
public string text {get;set;}
public int id {get;set;}
public Thing(string text, id)
{
this.text = text;
this.id = id;
}
public override string ToString()
{
return text;
}
}
and I am trying to populate DataGridView for example:
DataTable dt = new DataTable();
int Xnum = 100;
int Ynum = 100;
for (int i = 0; i < Xnum; i++)
dt.Columns.Add(i.ToString(), typeof(Thing));
for (int i = 0; i < Ynum; i++)
dt.Rows.Add();
and then
in some loop I try to fill values of the created cells in dt:
//loop
(dt.Rows[x][y] as Thing).text = "some text from loop";
(dt.Rows[x][y] as Thing).id = "some id from loop";
//end loop
And at the end:
DataGridView1.DataSource = dt;
Grid correctly populate with cells and rows but they are empty. I want them to have visible text on it from Thing.text fields.
I need to do it with custom object cause I want few things there to be available in future.
So how to do class so DataGridView can use it somehow to get text value to display on each cell?
This worked:
for (int x = 0; x < Xnum; ++x) {
for (int y = 0; y < Ynum; ++y) {
dt.Rows[y][x] = new Thing("Cell " + x.ToString() + ", " + y.ToString(), -1);
}
}
Make sure you are populating the table with "Things".

Get Cell Value from a DataTable in C#

Here is a DataTable dt, which has lots of data.
I want to get the specific Cell Value from the DataTable, say Cell[i,j]. Where,
i -> Rows and j -> Columns. I will iterate i,j's value with two forloops.
But I can't figure out how I can call a cell by its index.
Here's the code:
for (i = 0; i <= dt.Rows.Count - 1; i++)
{
for (j = 0; j <= dt.Columns.Count - 1; j++)
{
var cell = dt.Rows[i][j];
xlWorkSheet.Cells[i + 1, j + 1] = cell;
}
}
The DataRow has also an indexer:
Object cellValue = dt.Rows[i][j];
But i would prefer the strongly typed Field extension method which also supports nullable types:
int number = dt.Rows[i].Field<int>(j);
or even more readable and less error-prone with the name of the column:
double otherNumber = dt.Rows[i].Field<double>("DoubleColumn");
You probably need to reference it from the Rowsrather than as a cell:
var cellValue = dt.Rows[i][j];
You can iterate DataTable like this:
private void button1_Click(object sender, EventArgs e)
{
for(int i = 0; i< dt.Rows.Count;i++)
for (int j = 0; j <dt.Columns.Count ; j++)
{
object o = dt.Rows[i].ItemArray[j];
//if you want to get the string
//string s = o = dt.Rows[i].ItemArray[j].ToString();
}
}
Depending on the type of the data in the DataTable cell, you can cast the object to whatever you want.
To get cell column name as well as cell value :
List<JObject> dataList = new List<JObject>();
for (int i = 0; i < dataTable.Rows.Count; i++)
{
JObject eachRowObj = new JObject();
for (int j = 0; j < dataTable.Columns.Count; j++)
{
string key = Convert.ToString(dataTable.Columns[j]);
string value = Convert.ToString(dataTable.Rows[i].ItemArray[j]);
eachRowObj.Add(key, value);
}
dataList.Add(eachRowObj);
}
You can call the indexer directly on the datatable variable as well:
var cellValue = dt[i].ColumnName
If I have understood your question correctly you want to display one particular cell of your populated datatable? This what I used to display the given cell in my DataGrid.
var s = dataGridView2.Rows[i].Cells[j].Value;
txt_Country.Text = s.ToString();
Hope this helps

how to verify if my datatable is empty

hello again y have populate my datatable using 1 button an array, next button 2 is going to send my datatable to excel, so what a i do is this using C#, and asp.net:
out side of the button y declare my datable so i can be use in both buttons
System.Data.DataTable _myDataTable =new System.Data.DataTable();
button 1 fill datatable: for this example lets say only 10 columns, caract=number of cells
for (int k=0; k < 10; k++)
{
_myDataTable.Columns.Add();
}
for (int j=0; j < 10; j++)
{
TableRow r = new TableRow();
System.Data.DataRow row=_myDataTable.NewRow();
for (int i = 0; i < caract+1; i++)
{
row[i]=(datar[j,i].ToString());
}
_myDataTable.Rows.Add(row);
Table1.Rows.Add(r);
}
now button 2 allows to the user if he wants to save the data from the datatable to an excel, but first i verifi if the datable is empty
if(_myDataTable !=null || _myDataTable.Rows.Count == 0)
{
string name="productos";
Label2.Text="it has data";
}
else{Label2.Text="NO data"; }
no i recibe the text that i have data yupi for me, but when i press button 2 to send the datatable to excel, it creats the document however is empty,
so the next thing i would like to try is to verifi cell by cell if it has the data is supposed to have, but only have no idea how to extract the data from the datatable and to be display in a label.
I appreciate any help
Your if condition looks wrong on a couple of points.
This is how I would code it:
if(_myDataTable !=null && _myDataTable.Rows.Count > 0)
The above means - if _myDataTable is a valid object and it contains values.
JUAN you can define your DataTable in global scope. Then you can use it in both of your button event handlers.
For example:
namespace WebApplication1
{
public partial class _Default : System.Web.UI.Page
{
private DataTable _myDataTable;
public DataTable MyDataTable {
get
{
return _myDataTable;
}
set
{
_myDataTable = value;
}
}
protected void Button1_Click(object sender, EventArgs e)
{
for (int k=0; k < 10; k++)
{
MyDataTable.Columns.Add();
}
for (int j=0; j < 10; j++)
{
TableRow r = new TableRow();
System.Data.DataRow row = MyDataTable.NewRow();
for (int i = 0; i < caract+1; i++)
{
row[i]=(datar[j,i].ToString());
}
MyDataTable.Rows.Add(row);
Table1.Rows.Add(r);
}
}
protected void Button2_Click(object sender, EventArgs e)
{
if(MyDataTable !=null || MyDataTable.Rows.Count == 0)
{
string name="productos";
Label2.Text="it has data";
}
else
{
Label2.Text="NO data";
}
}
}
}
I know this is an old question but there is an easy way to solve this right now as follows:
if ((dataTableName?.Rows?.Count ?? 0) > 0)

Categories