How to loop all data in checkedlistbox in 'PROPER' way and print it on console or pop up on messagebox one by one?
I populated my clbPackages this way
// clbPackages is a checkedlistbox
SqlCommand scPackages = new SqlCommand("SELECT XXX FROM XXX", sqlConnection);
SqlDataReader readerPackages;
readerPackages = scPackages.ExecuteReader();
DataTable dtPackages = new DataTable();
dtPackages.Columns.Add("PACKAGE_GROUP_ID", typeof(string));
dtPackages.Columns.Add("PACKAGE_GROUP_NAME", typeof(string));
dtPackages.Load(readerPackages);
this.clbPackages.DataSource = dtPackages;
this.clbPackages.ValueMember = "PACKAGE_GROUP_ID";
this.clbPackages.DisplayMember = "PACKAGE_GROUP_NAME";
Now I have to loop that checkedlistbox because I am trying to check some in, my best try is this code below
foreach (var item in clbPackages.Items)
{
MessageBox.Show(item.ToString());
}
It only return xxx.xxx.DataRowView, and if I try to loop again the item it will show error "foreach statement cannot operate on variables of type 'object' because 'object' "
answered by Bjorn
other way to deal
foreach (object item in clbPackages.Items)
{
DataRowView castedItem = item as DataRowView;
string groupId= castedItem["PACKAGE_GROUP_ID"].ToString();
MessageBox.Show(groupId);
}
Sounds like the objects in the Items-collection is of type DataRowView. So if you convert each item to a DataRowView and get the value from that object you should be fine:
foreach (DataRowView item in clbPackages.Items)
{
MessageBox.Show(item["PACKAGE_GROUP_NAME"].ToString());
}
As far as I see you have access to your original data in original:
this.clbPackages.DataSource = dtPackages;
So all you have to do is to convert your DataSource to the original items (cast it to DataTable) and you can use all original data, isn't it?
To loop all data in a checkedListBox control try with this.
for(int i=0; i<clbPackages.Items.Count ; i++)
{
MessageBox.Show(clbPackages.Items[i].ToString());
}
Related
I have a table which's content is displayed at listbox. I want to delete rows that user has selected. How to know which rows to delete and how delete?
This is how I display listbox items:
DataSet AllPairs = new DataSet();
AllPairs.ReadXml(PathToPairsXML);
listBox1.DataSource = AllPairs.Tables[0];
listBox1.ValueMember = "PAIR_text";
listBox1.DisplayMember = "PAIR_text";
Listbox selection property is MultiExtended.
When you use DataTable as DataSource of your ListBox, items are of type DataRowView, so you can use Delete method of DataRowView or using Row property of DataRowView access the row behind that data row view and remove that row from your DataTable.
You can use this code:
this.listBox1.SelectedItems.Cast<DataRowView>()
.ToList()
.ForEach(item =>
{
//item.Delete();
//or
this.AllPairs.Tables[0].Rows.Remove(item.Row);
});
string selectedtext= "";
foreach (int i in listBox1 .SelectedIndices )
{
selectedtext= listBox1.Items[i].ToString ();
DataRow[] drCollection=AllPairs.Tables[0].Select("PAIR_text='"+selectedtext+"'");
if (drCollection.Length>0)
AllPairs.Tables[0].Rows.Remove(drCollection[0]);
}
This is so far the simplest way:
var selectedRows = listBox1.SelectedItems.Cast<DataRowView>().ToList();
foreach (var dr in selectedRows)
dr.Delete();
A small explanation. I'll be using the concrete types instead of var keyword for better understanding. The following line
listBox1.DataSource = AllPairs.Tables[0];
in equivalent to something like this
DataView dataView = AllPairs.Tables[0].DefaultView;
for (int i = 0; i < dataView.Count; i++)
{
DataRowView dataRowView = dataView[i];
listBox1.Items.Add(dataRowView);
}
Now when we know the list box contains DataRowView objects, although the SelectedItems returns items of type object, we can safely cast them back to a DataRowView and call Delete method.
But why we need ToList call? Because when we delete a row, the data source will send a notification to the list box and it will remove that item from the Items and SelectedItems. While it's not required, depending of the internal implementation this could destroy the selection. So in order to be absolutely sure that this will not happen, we buffer the initial selection in a list before proceeding with delete.
Since I haven't found anything that helped, I ask my question here:
I have a ListView where I select a whole row by click. Now I want to store these selected items into a List but don't know how this should work exactly.
List<String> itemSelected = new List<String>();
foreach (var selectedRow in listView1.SelectedItems)
{
itemSelected.Add(selectedRow);
}
That doesn't work because I need an index (selectedRow[?]) or something like that. How can I store the values of the first column when clicked the row?
EDIT: The problem is that the ListViewItems have the type "object"
The ListView gets populated this way:
using (SqlConnection connection = new SqlConnection(connectionQuery))
{
foreach (DataGridViewRow row in dataGridView1.SelectedRows)
{
col1 = row.Cells[col1.Text].Value.ToString();
col2 = row.Cells[col2.Text].Value.ToString();
col1Cells.Add(col1);
col2Cells.Add(col2);
}
}
You can do something like:
ListViewItem listViewItem = this.listView1.SelectedItems.Cast<ListViewItem>().FirstOrDefault();
if (listViewItem != null)
{
string firstColumn = listViewItem.Text;
string secondColumn = listViewItem.SubItems[0].Text;
// and so on with the SubItems
}
If you have more selected items and only need the values of the first columns you can use:
List<string> values = listView1.SelectedItems.Cast<ListViewItem>().Select(listViewItem => listViewItem.Text).ToList();
It's common to bind a ListView to the List of non-trivial types.
Then you can handle SelectedItemChanged or something like that. You receive the whole object (in type object) which you can cast to your custom type and retrieve any properties you want
I am trying to retrieve the displayed values of all items present in a comboBox.
First case: if the comboBox has been filled using a DataSource:
comboBox.DataSource = myDataSet.Tables[0];
comboBox.DisplayMember = "value";
comboBox.ValueMember = "id";
...I use this code:
foreach (DataRowView rowView in comboBox.Items) {
String value = rowView.Row.ItemArray[1].ToString();
// 1 corresponds to the displayed members
// Do something with value
}
Second case: if the comboBox has been filled with the comboBox.Items.Add("blah blah"), I use the same code, except I have to look in the first dimension of the ItemArray:
foreach (DataRowView rowView in comboBox.Items) {
String value = rowView.Row.ItemArray[0].ToString();
// 0 corresponds to the displayed members
// Do something with value
}
Now I would like to be able to retrieve all values without knowing the scheme used to fill the comboBox. Thus, I don't know if I have to use ItemArray[0] or ItemArray[1]. Is it possible? How could I do that?
You can try something like this:
string displayedText;
DataRowView drw = null;
foreach (var item in comboBox1.Items)
{
drw = item as DataRowView;
displayedText = null;
if (drw != null)
{
displayedText = drw[comboBox1.DisplayMember].ToString();
}
else if (item is string)
{
displayedText = item.ToString();
}
}
The Combobox would be populated with the DataSource property in the first case. Therefore its DataSource won't be null. In the second case, it would be null. So you could do an if-else with (comboBox1.DataSource==null) and then accordingly use ItemArray[0] or ItemArray[1].
Leito, you could check to see if the DataSource is a DataTable or not to determine which action to take.
if (comboBox.DataSource is DataTable)
{
// do something with ItemArray[1]
}
else
{
// do something with ItemArray[0]
}
I have used a CheckedListBox over my WinForm in C#. I have bounded this control as shown below -
chlCompanies.DataSource = dsCompanies.Tables[0];
chlCompanies.DisplayMember = "CompanyName";
chlCompanies.ValueMember = "ID";
I can get the indices of checked items, but how can i get checked item text and value. Rather how can i enumerate through CheckedItems accessing Text and Value?
Thanks for sharing your time.
Cast it back to its original type, which will be a DataRowView if you're binding a table, and you can then get the Id and Text from the appropriate columns:
foreach(object itemChecked in checkedListBox1.CheckedItems)
{
DataRowView castedItem = itemChecked as DataRowView;
string comapnyName = castedItem["CompanyName"];
int? id = castedItem["ID"];
}
EDIT: I realized a little late that it was bound to a DataTable. In that case the idea is the same, and you can cast to a DataRowView then take its Row property to get a DataRow if you want to work with that class.
foreach (var item in checkedListBox1.CheckedItems)
{
var row = (item as DataRowView).Row;
MessageBox.Show(row["ID"] + ": " + row["CompanyName"]);
}
You would need to cast or parse the items to their strongly typed equivalents, or use the System.Data.DataSetExtensions namespace to use the DataRowExtensions.Field method demonstrated below:
foreach (var item in checkedListBox1.CheckedItems)
{
var row = (item as DataRowView).Row;
int id = row.Field<int>("ID");
string name = row.Field<string>("CompanyName");
MessageBox.Show(id + ": " + name);
}
You need to cast the item to access the properties of your class.
foreach (var item in checkedListBox1.CheckedItems)
{
var company = (Company)item;
MessageBox.Show(company.Id + ": " + company.CompanyName);
}
Alternately, you could use the OfType extension method to get strongly typed results back without explicitly casting within the loop:
foreach (var item in checkedListBox1.CheckedItems.OfType<Company>())
{
MessageBox.Show(item.Id + ": " + item.CompanyName);
}
You can iterate over the CheckedItems property:
foreach(object itemChecked in checkedListBox1.CheckedItems)
{
MyCompanyClass company = (MyCompanyClass)itemChecked;
MessageBox.Show("ID: \"" + company.ID.ToString());
}
http://msdn.microsoft.com/en-us/library/system.windows.forms.checkedlistbox.checkeditems.aspx
foreach (int x in chklstTerms.CheckedIndices)
{
chklstTerms.SelectedIndex=x;
termids.Add(chklstTerms.SelectedValue.ToString());
}
To get the all selected Items in a CheckedListBox try this:
In this case ths value is a String but it's run with other type of Object:
for (int i = 0; i < myCheckedListBox.Items.Count; i++)
{
if (myCheckedListBox.GetItemChecked(i) == true)
{
MessageBox.Show("This is the value of ceckhed Item " + myCheckedListBox.Items[i].ToString());
}
}
Egypt Development Blog : Get value of checked item in CheckedListBox in vb.net
after bind CheckedListBox with data you can get value of checked items
For i As Integer = 0 To CheckedListBox1.CheckedItems.Count - 1
Dim XDRV As DataRowView = CType(CheckedListBox1.CheckedItems(i), DataRowView)
Dim XDR As DataRow = XDRV.Row
Dim XDisplayMember As String = XDR(CheckedListBox1.DisplayMember).ToString()
Dim XValueMember As String = XDR(CheckedListBox1.ValueMember).ToString()
MsgBox("DisplayMember : " & XDisplayMember & " - ValueMember : " & XValueMember )
Next
now you can use the value or Display of checked items in CheckedListBox from the 2 variable XDisplayMember And XValueMember in the loop
hope to be useful.
I've already posted GetItemValue extension method in this post
Get the value for a listbox item by
index. This extension
method will work for all ListControl classes including
CheckedListBox, ListBox and ComboBox.
None of the existing answers are general enough, but there is a general solution for the problem.
In all cases, the underlying Value of an item should be calculated regarding to ValueMember, regardless of the type of data source.
The data source of the CheckedListBox may be a DataTable or it may be a list which contains objects, like a List<T>, so the items of a CheckedListBox control may be DataRowView, Complex Objects, Anonymous types, primary types and other types.
GetItemValue Extension Method
We need a GetItemValue which works similar to GetItemText, but return an object, the underlying value of an item, regardless of the type of object you added as item.
We can create GetItemValue extension method to get item value which works like GetItemText:
using System;
using System.Windows.Forms;
using System.ComponentModel;
public static class ListControlExtensions
{
public static object GetItemValue(this ListControl list, object item)
{
if (item == null)
throw new ArgumentNullException("item");
if (string.IsNullOrEmpty(list.ValueMember))
return item;
var property = TypeDescriptor.GetProperties(item)[list.ValueMember];
if (property == null)
throw new ArgumentException(
string.Format("item doesn't contain '{0}' property or column.",
list.ValueMember));
return property.GetValue(item);
}
}
Using above method you don't need to worry about settings of ListBox and it will return expected Value for an item. It works with List<T>, Array, ArrayList, DataTable, List of Anonymous Types, list of primary types and all other lists which you can use as data source. Here is an example of usage:
//Gets underlying value at index 2 based on settings
this.checkedListBox.GetItemValue(this.checkedListBox.Items[2]);
Since we created the GetItemValue method as an extension method, when you want to use the method, don't forget to include the namespace in which you put the class.
This method is applicable on ComboBox and CheckedListBox too.
try:
foreach (var item in chlCompanies.CheckedItems){
item.Value //ID
item.Text //CompanyName
}
You may try this :
string s = "";
foreach(DataRowView drv in checkedListBox1.CheckedItems)
{
s += drv[0].ToString()+",";
}
s=s.TrimEnd(',');
I am confused on DataTable.DefaultView.Sort. Here is the segment of the code I want to use it in.
actionLogDT.DefaultView.Sort = "StartDate";
foreach (CustomerService.ActionLogStartEndRow logRow in actionLogDT)
{
// code here
}
The samples I have seen don't use the foreach loop and thus is confusing me on how to process this. It isn't sorting as I thought it should be.
I see that .DefaultView returns a view, and .Table gives a compile error.
actionLogDT.DefaultView.Sort = "StartDate";
actionLogDT = actionLogDT.DefaultView.ToTable();
Sorting the view won't change the sort order of the data in the table, just the order in the view. It should work if you do your foreach on the view instead, casting the row from the DataRowView back to your strongly typed row.
foreach (DataRowView logRowView in actionLogDT.DefaultView)
{
CustomerService.ActionLogStartEndRow logRow = logRowView.Row as CustomerService.ActionLogStartEndRow;
// code here
}
I had to take a slightly different approach. This post was the closest I could find to get my code to work. Here is the working result:
actionLogDT.DefaultView.Sort = "StartDate";
DataView dv = actionLogDT.DefaultView;
foreach (DataRowView logRow in dv) { . . . }
From there I just have to cast the value back into it's proper type.
(string)logRow["Status"].ToString()
foreach (var logRow in actionLogDT.DefaultView.ToDataTable()) { ... }
Additionally, Since it seemed like you wanted to loop through records, you can just loop through the dataRowView objects in the DefaultView.
foreach (DataRowView drv in table.DefaultView)
{
string strValue = drv["ColumnName"].ToString();
// its also worth mentioning that a DataRowView has a Row
strValue = drv.Row["ColumnName"].ToString();
}
Please try this:
actionLogDT.DefaultView.Sort = "["+actionLogDT.Columns[0].ColumnName+"] asc";
Just curious: Why are you using the DataRowView?
i.e.
foreach (DataRow row in actionLogDT.Rows)
{
Console.WriteLine(row["Status"]);
}
If you need a datatable back then you can do something like:
var dv = actionLogDT.DefaultView;
dv.Sort = "StartDate";
actionLogDT = dv.ToTable();
In VB.NET, the code below was the best way for me to invoke the solution. Just copy your origtable to a DataView, and then the dataview can be sorted with a simple .sort command, and then set a new table equal to the sorted view (of your original table). Use the sorted table dt for your processing thereafter.
Dim View1 As DataView = New DataView(origtable)
View1.Sort = "LastName"
Dim dt As DataTable = View1.ToTable