I have a CheckedListBox and I would like to check all the items that are in another List.
This code does not work since the CheckedItems property is read-only and the types do not match, but it gives the best idea of what I want to do.
checkedListBox1.DataSource = DataSetSelectAll().Tables[0];
checkedListBox1.ValueMember = "id_table";
checkedListBox1.DisplayMember = "name";
List<tableClass> list = MyCheckedList();
checkedListBox1.CheckedItems = list;
I know this is wrong but do not know how to explain it better.
Its not possible to set(check) many items at a time like this, checkedListBox1.CheckedItems = list;
better you can use for loop like:
List<tableClass> list = MyCheckedList();
for (int count = 0; count < checkedListBox1.Items.Count; count++)
{
if (list.Contains(checkedListBox1.Items[count].ToString()))
{
checkedListBox1.SetItemChecked(count, true);
}
}
andy's answer is right but I have an easier solution. My solution works in windows application.
DataTable dt = MyCheckedList();
foreach (DataRow dr in dt.Rows)
{
for (int i = 0; i < checkedListBox1.Items.Count; i++)
{
if (dr["valueMember"].ToString() == ((DataRowView)checkedListBox1.Items[i])[0].ToString())
{
checkedListBox1.SetItemChecked(i, true);
}
}
}
Note: dt must fill with a dataTable which has all checkedList Values.
I'm not sure why, but I SetItemChecked(index, tf) wasn't giving me what I wanted. This is how I solved it - explicitly setting the CheckedState.
for (int i = 0; i < myCheckedListBox.Items.Count; i++)
{
if (boolList[i])
{
myCheckedListBox.SetItemCheckState(i, CheckState.Checked);
} else
{
myCheckedListBox.SetItemCheckState(i, CheckState.Unchecked);
}
}
Related
I have a function that sets column values for all rows:
The code that sets this:
//Update the engineers for all rows
Btn_ValidateClick_ItemClick(object sender,ItemClickEventArgs e)
{
UpdateTotalTime(gridView);
}
private void UpdateEngineers(DevExpress.XtraGrid.Views.Base.ColumnView View)
{
//Column name that need to be updated (set)
DevExpress.XtraGrid.Columns.GridColumn col = View.Columns.ColumnByFieldName("Engineers");
try
{
int dataRowCount = View.DataRowCount;
for (int i = 0; i < dataRowCount; i++)
{
GridView detail = (GridView)gridView.GetDetailView(i, 0);
string language = gridView.GetRowCellValue(i, "Language").ToString();
for (int y = 0; y < gridView.GetDetailView(i, 0).RowCount; y++)
{
//Add all values found in a detail column to an arraylist
values.Add(detail.GetRowCellValue(y, "EngineerInitials").ToString());
}
if (values.Count >0 )
object t = //string join ...
View.SetRowCellValue(i, col, t);
}
else
{
object t = "No engineers"
View.SetRowCellValue(i, col, t);
}
}
}
}
}
The problem is that now, I want it only to set it for the rows that are selected.
I tried using the .GetSelectedRows()-function and adding the rows to an ArrayList, but this doesn't allow customability really:
private void UpdateTotalTime(DevExpress.XtraGrid.Views.Base.ColumnView View)
{
ArrayList selectedRows = new ArrayList();
for (int i = 0; i < gridView.SelectedRowsCount; i++)
{
if (gridView.GetSelectedRows()[i] >= 0)
selectedRows.Add(gridView.GetDataRow(gridView.GetSelectedRows()[i]));
}
try
{
int count = View.GetSelectedRows().Count();
for (int i = 0; i < selectedRows.Count; i++)
{
//This gets the first row of the count, not the first selected row
GridView detail = (GridView)gridView.GetDetailView(i,0);
}
}
If I select the 3 bottom rows, the first 3 get updated. Why is this?
You are adding all the selected rows to your selectedRows ArrayList. But after that, you are not using it for anything.
I guess what you want (I've never used devexpress controls) is using those selectedrows RowHandle to pass it to the GetDetailView method. According to the GetSelectedRows documentation, the method returns the int handles of the selected rows, so your code should look like this:
First, you must save the DataRow handles, not the DataRow itself, so you must change in your code this line:
selectedRows.Add(gridView.GetDataRow(gridView.GetSelectedRows()[i]));
into this:
selectedRows.Add(gridView.GetSelectedRows()[i]);
And then, change your loop into this:
for (int i = 0; i < selectedRows.Count; i++)
{
int rowHandle = (int)selectedRows[i];
GridView detail = (GridView)gridView.GetDetailView(rowHandle,0);
}
In fact, you could do everything in just one loop:
private void UpdateTotalTime(DevExpress.XtraGrid.Views.Base.ColumnView View)
{
for (int i = 0; i < gridView.SelectedRowsCount; i++)
{
int rowHandle = gridView.GetSelectedRows()[i];
GridView detail = (GridView)gridView.GetDetailView(rowHandle,0);
}
}
I want to make it so that through a loop, it will select an item from the listbox. I was thinking about doing a for loop. This is (basically) what I want to accomplish:
for (int i = 0; i < lbRooms.Items.Count; i++)
{
lbRooms.Items.Select(i);
// do stuff here with the selected item
}
I know thats not how it works, but I want it to do it like that. I appreciate all the help, thanks =D
EDIT: I think this will work, but I'm sure it can be improved:
for (int i = 0; i < lbRooms.Items.Count; i++)
{
lbRooms.SetSelected(i, true);
}
Try:
lbRooms.setSelected(i, true);
instead of:
lbRooms.Items.Select(i);
You can't select your items like that, You can use indexer to get your item:
for (int i = 0; i < lbRooms.Items.Count; i++)
{
var currentItem = lbRooms.Items[i];
}
If you want to select that item you can set Selected property to true:
currentItem.Selected = true;
foreach (listitem item in lbRooms.Items)
//do item manipulation here
I am trying to populate a DataGridView based on the selected item in a ComboBox, I have this part working.
However, I need to be able to clear the grid before adding the new data from a new item rather than it just adding on to the end.
How do I clear a DataGridView before adding items to it?
Firstly, null the data source:
this.dataGridView.DataSource = null;
Then clear the rows:
this.dataGridView.Rows.Clear();
Then set the data source to the new list:
this.dataGridView.DataSource = this.GetNewValues();
If it's bound to a datasource -
dataGridView.DataSource=null;
dataGridView.Rows.Clear();
Worked for me.
You can clear DataGridView in this manner
dataGridView1.Rows.Clear();
dataGridView1.Refresh();
If it is databound then try this
dataGridView1.Rows.Clear() // If dgv is bound to datatable
dataGridView1.DataBind();
IF you want to clear not only Data, but also ComboBoxes, Checkboxes, try
dataGridView.Columns.Clear();
DataGrid.DataSource = null;
DataGrid.DataBind();
You can assign the datasource as null of your data grid and then rebind it.
dg.DataSource = null;
dg.DataBind();
You could take this next instruction and would do the work with lack of perfomance. If you want to see the effect of that, put one of the 2 next instructions (Technically similars) where you need to clear the DataGridView into a try{} catch(...){} finally block and wait what occurs.
while (dataGridView1.Rows.Count > 1)
{
dataGridView1.Rows.RemoveAt(0);
}
foreach (object _Cols in dataGridView1.Columns)
{
dataGridView1.Columns.RemoveAt(0);
}
You improve this task but its not enough, there is a problem to reset a DataGridView, because of the colums that remains in the DataGridView object. Finally I suggest, the best way i've implemented in my home practice is to handle this gridView as a file with rows, columns: a record collection based on the match between rows and columns. If you can improve, then take your own choice a) or b): foreach or while.
//(a): With foreach
foreach (object _Cols in dataGridView1.Columns)
{
dataGridView1.Columns.RemoveAt(0);
}
foreach(object _row in dataGridView1.Rows){
dataGridView1.Rows.RemoveAt(0);
}
//(b): With foreach
while (dataGridView1.Rows.Count > 1)
{
dataGridView1.Rows.RemoveAt(0);
}
while (dataGridView1.Columns.Count > 0)
{
dataGridView1.Columns.RemoveAt(0);
}
Well, as a recomendation Never in your life delete the columns first, the order is before the rows after the cols, because logically the columns where created first and then the rows.It would be a penalty in terms of correct analisys.
foreach (object _Cols in dataGridView1.Columns)
{
dataGridView1.Columns.RemoveAt(0);
}
foreach (object _row in dataGridView1.Rows)
{
dataGridView1.Rows.RemoveAt(0);
}
while (dataGridView1.Rows.Count > 1)
{
dataGridView1.Rows.RemoveAt(0);
}
while (dataGridView1.Columns.Count > 0)
{
dataGridView1.Columns.RemoveAt(0);
}
Then, Put it inside a function or method.
private void ClearDataGridViewLoopWhile()
{
while (dataGridView1.Rows.Count > 1)
{
dataGridView1.Rows.RemoveAt(0);
}
while (dataGridView1.Columns.Count > 0)
{
dataGridView1.Columns.RemoveAt(0);
}
}
private void ClearDataGridViewForEach()
{
foreach (object _Cols in dataGridView1.Columns)
{
dataGridView1.Columns.RemoveAt(0);
}
foreach (object _row in dataGridView1.Rows)
{
dataGridView1.Rows.RemoveAt(0);
}
}
Finally, call your new function ClearDataGridViewLoopWhile(); or ClearDataGridViewForEach(); where you need to use it, but its recomended when you are making queries and changing over severall tables that will load with diferents header names in the grieView. But if you want preserve headers here there is a solution given.
dataGridView1.Rows.Clear();
dataGridView1.Refresh();
If you want to clear all the headers as well as the data, for example if you are switching between 2 totally different databases with different fields, therefore different columns and column headers, I found the following to work. Otherwise when you switch you have the columns/ fields from both databases showing in the grid.
dataTable.Dispose();//get rid of existing datatable
dataTable = new DataTable();//create new datatable
datagrid.DataSource = dataTable;//clears out the datagrid with empty datatable
//datagrid.Refresh(); This does not seem to be neccesary
dataadapter.Fill(dataTable); //assumming you set the adapter with new data
datagrid.DataSource = dataTable;
private void ClearGrid()
{
if(this.InvokeRequired) this.Invoke(new Action(this.ClearGrid));
this.dataGridView.DataSource = null;
this.dataGridView.Rows.Clear();
this.dataGridView.Refresh();
}
refresh the datagridview and refresh the datatable
dataGridView1.Refresh();
datatable.Clear();
datatable.Clear();
dataGridView1.DataSource = datatable;
For having a Datagrid you must have a method which is formatting your Datagrid. If you want clear the Datagrid you just recall the method.
Here is my method:
public string[] dgv_Headers = new string[] { "Id","Hotel", "Lunch", "Dinner", "Excursions", "Guide", "Bus" }; // This defined at Public partial class
private void SetDgvHeader()
{
dgv.Rows.Clear();
dgv.ColumnCount = 7;
dgv.RowHeadersVisible = false;
int Nbr = int.Parse(daysBox.Text); // in my method it's the textbox where i keep the number of rows I have to use
dgv.Rows.Add(Nbr);
for(int i =0; i<Nbr;++i)
dgv.Rows[i].Height = 20;
for (int i = 0; i < dgv_Headers.Length; ++i)
{
if(i==0)
dgv.Columns[i].Visible = false; // I need an invisible cells if you don't need you can skip it
else
dgv.Columns[i].Width = 78;
dgv.Columns[i].HeaderText = dgv_Headers[i];
}
dgv.Height = (Nbr* dgv.Rows[0].Height) + 35;
dgv.AllowUserToAddRows = false;
}
dgv is the name of DataGridView
The solution is:
dataGridView1.Rows.RemoveAt(0);
Clears the grid and preserves the columns.
YourGrid.Items.Clear();
YourGrid.Items.Refresh();
This is working to me
'int numRows = dgbDatos.Rows.Count;
for (int i = 0; i < numRows; i++)
{
try
{
int max = dgbDatos.Rows.Count - 1;
dgbDatos.Rows.Remove(dgbDatos.Rows[max]);
btnAgregar.Enabled = true;
}
catch (Exception exe)
{
MessageBox.Show("No se puede eliminar " + exe, "",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}`
Solution is:
while (dataGridView1.RowCount > 1)
{
dataGridView1.Rows.RemoveAt(0);
}
You could take this next instruction and would do the work with lack of perfomance. If you want to see the effect of that, put one of the next instruction where you need to clear the DataGridView into a try{} catch(...){} finally block and wait what occurs.
while (dataGridView1.Rows.Count > 1)
{
dataGridView1.Rows.RemoveAt(0);
}
while (dataGridView1.Columns.Count > 0)
{
dataGridView1.Columns.RemoveAt(0);
}
my DataTable has over 1000 columns and I want to display values on the datagridview. Because of the FillWeigth problem I use the following method to fill the gridview,
public bool TransferDataTableToGrid(DataGridView dataGrid, DataTable dataTable)
{
dataGrid.SuspendLayout();
if ((dataGrid != null) && (dataTable != null))
{
dataGrid.Columns.Clear();
dataGrid.AutoGenerateColumns = false;
dataGrid.DataSource = dataTable;
for (int i = 0; i < dataTable.Columns.Count; i++)
{
DataGridViewColumn column = new DataGridViewColumn();
column.Name = dataTable.Columns[i].ColumnName;
column.FillWeight = 1;
column.CellTemplate = new DataGridViewTextBoxCell();
column.ValueType = dataTable.Columns[i].DataType;
dataGrid.Columns.Add(column);
}
for (int i = 0; i < dataTable.Columns.Count; i++)
{
for (int ii = 0; ii < dataTable.Rows.Count; ii++)
{
dataGrid[i, ii].Value = dataTable.Rows[ii][i];
}
}
}
dataGrid.ResumeLayout();
return true;
}
and sometimes I have an effect that my gridview is empty. Only after second execution data is displayed. Do you have any ideas, why...?
Thanks.
I recommend to use paging, i mean that you can show about 20 columns with navigation buttons
under your grid, it's like Google or others... even your are not programming a web application.
Use binding source to fill your grid
SqlDataAdapter adapter = new SqlDataAdapter(database.cmd);
dataSet1.Tables.Clear();
adapter.Fill(dataSet1, "Table");
bs = new BindingSource();
bs.DataSource = dataSet1.Tables["Table"];
dataGridView1.DataSource = bs;
now you dont need to worry about creating columns and fill cells in loops and its much better performance
Bind Data to Datagridview
Well, I solved my problem. With Ivan's suggestion I tried the alternative way to fill data: instead of using DataSource I add new rows manually
foreach (DataRow row in dataTable.Rows)
{
var dataGridRow = new DataGridViewRow();
dataGridRow.CreateCells(dataGrid);
for (int i = 0; i < row.ItemArray.Length; i++)
{
dataGridRow.Cells[i].Value = row.ItemArray[i];
}
dataGrid.Rows.Add(dataGridRow);
}
...and it works - data in dgv is displayed. Thanks!
in the next example how can I know the current row index?
foreach (DataRow temprow in temptable.Rows)
{
//this.text = temprow.INDEX????
}
You have to create one yourself
var i = 0;
foreach (DataRow temprow in temptable.Rows)
{
this.text = i;
// etc
i++;
}
or you can just do a for loop instead.
I have a type in MiscUtil which can help with this - SmartEnumerable. It's a dumb name, but it works :) See the usage page for details, and if you're using C# 3 you can make it even simpler:
foreach (var item in temptable.Rows.AsSmartEnumerable())
{
int index = item.Index;
DataRow value = item.Value;
bool isFirst = item.IsFirst;
bool isLast = item.IsLast;
}
If you can use Linq, you can do it this way:
foreach (var pair in temptable.Rows.Cast<DataRow>()
.Select((r, i) => new {Row = r, Index = i}))
{
int index = pair.Index;
DataRow row = pair.Row;
}
You actually Don't. One of the beauties with foreach is that you don't have the extra set of code handling incrementing and checks on the length.
If you want to have your own Index you would have to do something like this
int rowindex = 0;
foreach (DataRow temprow in temptable.Rows)
{
//this.text = temprow.INDEX????
this.text = rowindex++;
}
int rowIndex = temptable.Rows.IndexOf(temprow);
It's not possible with a standard foreach loop. The simplest way is to use a for loop
for ( int i = 0; i < temptable.Rows.Count; i++ ) {
DataRow temprow = (DataRow)temptable.Rows[i];
...
}
Another option is to use an extension method
public static void ForEachIndex<T>(this IEnumerable<T> e, Action<T,int> del) {
var i = 0;
foreach ( var cur in e ) {
del(cur,i);
}
}
...
temptable.Rows.Cast<DataRow>.ForEachIndex((cur,index)
{
...
});
Hey there's a much faster way I think. No iteration required!
First, declare a static variable for the Friend RowID Field of the DataRow:
Private Shared RowIDFieldInfo As System.Reflection.FieldInfo = GetType(DataRow).GetField("_rowID", System.Reflection.BindingFlags.NonPublic Or System.Reflection.BindingFlags.Instance)
Then All you need to do to use it is:
RowIDFieldInfo.GetValue(MyDataRow) - 1
I have not tested this after resorting or filtering.
In my case I haven't a need to do that, so this works.
Better late than never...
foreach (DataRow temprow in temptable.Rows)
{
temptable.Rows.IndexOf(temprow);
}
Write any Cell number and get RowIndex
foreach (var item in datagridview.Rows)
{
//TextBox1.Text= item.Cells[0].RowIndex.ToString();
}
Either use a for-loop, or use an integer follow along:
int count =0;
foreach (DataRow temprow in temptable.Rows)
{
//count is the index of the row in the array temptable.Rows
//this.text = temprow.INDEX????
++count;
}
You can use the standard for loop to get the index
for(int i=0; i<temptable.Rows.Count; i++)
{
var index = i;
var row = temptable.Rows[i];
}
While LFSR's answer is right, I'm pretty sure calling .IndexOf on just about any collection/list is going to enumerate the list until it finds a the matching row. For large DataTable's this could be slow.
It might be better to for (i = 0; i < temptable.Rows.Count; i++) { ... } over the table. That way you have the index without imposing a find-the-index tax.
The alternative way to retrieve data by using index instead of using column name
foreach (DataRow temprow in temptable.Rows)
{
String col1 = temprow[0].ToString().Trim();
String col2 = temprow[1].ToString().Trim();
}
Hope it help