How to get selected index from selected value in combo box C# - c#

Is there any built-in method for getting selected index from selected value in ComboBox control C#. If not, how can I built my own one
Thanks in advance

I think you're looking for the SelectedIndex property.
int index = comboref.SelectedIndex
As you're looking for the index of a specific value not the selected one you can do
int index = comboref.Items.IndexOf("string");
and it will tell you which Index has "string" on the combobox

You can use combobox1.Items.IndexOf("string") which will return the index within the collection of the specified item
Or use combobox1FindString("string") or findExactString("string") which will return the first occurence of the specified item. You can also give it a second parameter corresponding to the startIndex to start searching from that index.
I Hope I answered your question !!

OP: What I want is to get index from value. i.e: int seletedIndex = comboBox.getIndexFromKnownSelectedValue(value)
Get Item by Value and Get Index by Value
You need to scan the items and for each item get the value based on the SelectedValue field and then get the index of item. To do so, you can use this GetItemValue extension method and get item and index this way:
//Load sample data
private void Form1_Load(object sender, EventArgs e)
{
comboBox1.DataSource = Enumerable.Range(1, 5)
.Select(x => new { Name = $"Product {x}", Id = x }).ToList();
comboBox1.DisplayMember = "Name";
comboBox1.ValueMember = "Id";
}
private void button1_Click(object sender, EventArgs e)
{
//Knows value
var value = 3;
//Find item based on value
var item = comboBox1.Items.Cast<Object>()
.Where(x => comboBox1.GetItemValue(x).Equals(value))
.FirstOrDefault();
//Find index
var index = comboBox1.Items.IndexOf(item);
//Set selected index
comboBox1.SelectedIndex = index;
}

No, there is no any built-in method for getting selected index from selected value in ComboBox control C#.
But you can create your own function to get the same.
Usage:
int index = CmbIdxFindByValue("YourValue", YourComboBox);
Function:
private int CmbIdxFindByValue(string text, ComboBox cmbCd)
{
int c = 0;
DataTable dtx = (DataTable)cmbCd.DataSource;
if (dtx != null)
{
foreach (DataRow dx in dtx.Rows)
{
if (dx[cmbCd.ValueMember.ToString()].ToString() == text)
return c;
c++;
}
return -1;
} else
return -1;
}

Related

How to set Item checked in a checkedlistbox based on Key value?

I have checkedListbox for which i am binding values with Id and Values, when the items are checked i'm saving the Id's in the database, when the form loads i want the checkedListbox items to be checked based on the Id's
I am only able to bind the checkedlistbox based on the index as below , the other alternative i see is getting the Index of the value and checking it but this will not work in my case as i have only the Id's of the checkedlistbox items which needs to be checked.
int index = checkedListBox1.Items.IndexOf("42");
checkedListBox1.SetItemChecked(index , true);
this is how I am binding values
ccBoxitem item = new ccBoxitem(a.name, a.id);
checkedListBox1.items.add(item);
public ccBoxitem (string name, int val)
{
this.name = name;
this.val = val;
}
How can I check the checkedlistbox based on the id's ?
For example, you can loop through your items, then check the one you want:
private void CheckItem(int id)
{
for (int i = 0; i < checkedListBox1.Items.Count; i++)
{
if ((checkedListBox1.Items[i] as ccBoxitem)?.val == id)
{
checkedListBox1.SetItemChecked(i, true);
}
}
}
usage:
var id = GetId();
CheckItem(id);
You can use below method it will select needed item by its value first then check the selected item
void CheckItem(CheckedListBox checkedListBox, int id)
{
checkedListBox.SelectedItem = checkedListBox.Items.OfType<ccBoxitem>().ToList().FirstOrDefault(i => i.val == id);
checkedListBox.SetItemChecked(checkedListBox.SelectedIndex, true);
checkedListBox.SelectedItem = null; // To clear selection if needed
}
And you can call it as below
CheckItem(checkedListBox1, 3);
CheckItem(checkedListBox1, 6);

How to filter ListView by using a ComboBox?

I have a TextBox that searches whatever I have in my ListView. I would like to have a ComboBox that will allow the user to “Show All”, “Show Match” and “Show Non Match” within the ListView depending on search criteria.
private void SearchBtn_Click(object sender, EventArgs e)
{
int count = 0, searchStartIndex = selectedIndexPos = 0;
// Clear previously selected indices
listView.SelectedIndices.Clear();
string target = searchTextBox.Text;
// Search for item with text from the search text box, including subItems, from searchStartIndex, not a prefixSearch
ListViewItem item = listView.FindItemWithText(target, true, searchStartIndex, false);
/*----------------------------------------------------------------------------------------------------*
* While the search results in an item found continue searching. *
*----------------------------------------------------------------------------------------------------*/
while (item != null)
{
count++;
// Update progressBar
progressBar.Value = (int)((float)searchStartIndex / listView.VirtualListSize * 100);
ListView.SelectedIndexCollection indexes = listView.SelectedIndices;
if (!indexes.Contains(item.Index))
{
listView.SelectedIndices.Add(item.Index);
}
/*----------------------------------------------------------------------------------------------------*
* Set the start index to the index after the last found, if valid start index search for next item.*
*----------------------------------------------------------------------------------------------------*/
if ((searchStartIndex = item.Index + 1) < listView.VirtualListSize)
{
item = listView.FindItemWithText(searchTextBox.Text, true, searchStartIndex, false);
// count++;
}
else
{
item = null;
}
}
if (listView.SelectedIndices.Count == 0)
{
MessageBox.Show("Find item with text \"" + searchTextBox.Text + "\" has no result.");
}
else
{
RefilterListView();
listView.EnsureVisible(listView.SelectedIndices[0]);
}
}
I would like to have my items in the 'ComboBox' to help filter my 'ListView'. The "Show All" should display all contents of 'ListView' along with item that was searched, the "Show Match" should show only the searched item removing everything else that doesn't match the search and "Show Non Match" should show all of the contents from 'ListView' that doesn't match the searched item.
I can't do it exactly in your case. But I hope I realize it. I mean this is just a solution. You can customize it for your case.
First of all, put a BindingSource on your Form and bind it to your data:
bindingSource1.DataSource = data;
Then bind your ListView(actually DataGridView) to the BindingSource:
dataGridView1.DataSource = bindingSource1;
And then define an enum like this:
public enum Something
{
ShowMatch = 1,
ShowNonMatch = 2
}
Now, put a ComboBox on your Form and add your options to it:
comboBox1.Items.Add("Show All");
comboBox1.Items.Add("ShowMatch");
comboBox1.Items.Add("ShowNonMatch");
comboBox1.SelectedIndex = 0;
After that, you can catch the selected item in SelectedIndexChanged:
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (comboBox1.SelectedIndex == 0)
bindingSource1.Filter = null;
else
bindingSource1.Filter = $"Name = '{comboBox1.SelectedItem.ToString()}'";
}

ListView.FindItemWithText inside WHILE loop fails after first ListView line

I want change the content of 2nd column of each line of ListView with diferents data according with is found via FindItemWith.
My trouble is that from of 2nd line is be overriding the previous columns, for example when i want change the content searching a text that stays on first line works fine, see:
Already when i want change the content searching a text that stays on second line this happens:
This is the code:
public void fillData(string search, string data, ListView haystack)
{
if (haystack.Items.Count > 0)
{
int idx = 0;
ListViewItem found;
while (idx < haystack.Items.Count)
{
found = haystack.FindItemWithText(search, true, idx);
if (found != null)
{
haystack.Items[idx].SubItems[1].Text = data.ToString();
}
idx++;
}
}
}
private void button3_Click(object sender, EventArgs e)
{
int i = 0;
while (i < 3)
{
ListViewItem item = new ListViewItem();
item.Text = i.ToString();
item.SubItems.Add("192.168.0." + i.ToString());
listView1.Items.Add(item);
i++;
}
}
private void button1_Click(object sender, EventArgs e)
{
fillData("192.168.0.0", "AAA", listView1);
}
private void button2_Click(object sender, EventArgs e)
{
fillData("192.168.0.1", "BBB", listView1);
}
This is because the overload function you used for FindItemWithText, keeps searching all the items from the index you passed in.
When the loop has idx = 0 then FindItemWithText will try to search all three items 0,1,2.
When the loop has idx = 1 then FindItemWithText will try to search two items 1,2.
When the loop has idx = 2 then FindItemWithText will try to search only one item 2.
So now in the first case, As you are searching for first item, your loop found it only once. But where as in second case you are searching for second item, it was found twice both (idx = 0 ---- 0,1,2) and (idx = 1 ---- 1,2) iterations. So you are updating two values both for idx=0 and idx = 1.
Here is the documentation link
https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.listview.finditemwithtext?view=netframework-4.7.2#System_Windows_Forms_ListView_FindItemWithText_System_String_System_Boolean_System_Int32_
Any how FindItemWithText returns the System.Windows.Forms.ListViewItem. Just search once from zero. Use that item to update.

Listview Sort by Column

I have an assignment about ListView sort by Column using C# Windows Form and the codes that I got from MSDN didn't work. Can anybody find out what's wrong with the codes? Everytime I click the ListView Column nothing happens.
Here's the code, I also added the items that will show in my ListView
private int sortColumn = -1;
private void listView1_ColumnClick(object sender, ColumnClickEventArgs e)
{
// Determine whether the column is the same as the last column clicked.
if (e.Column != sortColumn)
{
// Set the sort column to the new column.
sortColumn = e.Column;
// Set the sort order to ascending by default.
listView1.Sorting = SortOrder.Ascending;
}
else
{
// Determine what the last sort order was and change it.
if (listView1.Sorting == SortOrder.Ascending)
listView1.Sorting = SortOrder.Descending;
else
listView1.Sorting = SortOrder.Ascending;
}
// Call the sort method to manually sort.
listView1.Sort();
// Set the ListViewItemSorter property to a new ListViewItemComparer
// object.
this.listView1.ListViewItemSorter = new ListViewItemComparer(e.Column,
listView1.Sorting);
}
private void FillItems()
{
// Add items
ListViewItem item1 = new ListViewItem("Nipun Tomar");
item1.SubItems.Add("1");
item1.SubItems.Add("10/11/2000");
ListViewItem item2 = new ListViewItem("First Last");
item2.SubItems.Add("2");
item2.SubItems.Add("12/12/2010");
ListViewItem item3 = new ListViewItem("User User");
item3.SubItems.Add("3");
item3.SubItems.Add("12/01/1800");
ListViewItem item4 = new ListViewItem("Sample");
item4.SubItems.Add("4");
item4.SubItems.Add("05/30/1900");
// Add the items to the ListView.
listView1.Items.AddRange(
new ListViewItem[] {item1, item2, item3, item4});
}
private void Form1_Load(object sender, EventArgs e)
{
FillItems();
}
public class ListViewItemComparer : IComparer
{
private int col;
private SortOrder order;
public ListViewItemComparer()
{
col = 0;
order = SortOrder.Ascending;
}
public ListViewItemComparer(int column, SortOrder order)
{
col = column;
this.order = order;
}
public int Compare(object x, object y)
{
int returnVal= -1;
returnVal = String.Compare(((ListViewItem)x).SubItems[col].Text,
((ListViewItem)y).SubItems[col].Text);
// Determine whether the sort order is descending.
if (order == SortOrder.Descending)
// Invert the value returned by String.Compare.
returnVal *= -1;
return returnVal;
}
}
Note: I added the columns in the design form.
Here's what my assignment looks like:
You dont have any columns in your list view. They are just items. thats why the event listView1_ColumnClick never fires. (also make sure you have added this event to your list view.)
Add this at first of your Form1_Load event to initialize columns.
// set view mode to see columns
listView1.View = View.Details;
// 100 is just a length of column. HorizontalAlignment.Left starts from left side
listView1.Columns.Add("Name", 100, HorizontalAlignment.Left);
listView1.Columns.Add("Number", 100, HorizontalAlignment.Left);
listView1.Columns.Add("Date", 100, HorizontalAlignment.Left);
Now you see the columns which you can select them to sort items by that column.
Note that i just added 3 columns. so list view will show each item with 2 of their SubItems under columns by order.
As you requested to post the gif. Here is it :)
You call listView1.Sort()before setting the comparer: this.listView1.ListViewItemSorter = ...
Just invert the two lines.
Also, note that you are using string.Compare for all columns, which, I think, it's not what you want for column 3 (date)
[Edit]:
Just realized now the setting the value for ListviewItemSorter cause the LV to sort: your code seems to work even without calling listView1.Sort()
Problem must be somewhere else. Try with debugger setting breakpoints...
private void lvw_ColumnClick(object sender, System.Windows.Forms.ColumnClickEventArgs e)
{
ListViewColumnSorter sorter = new ListViewColumnSorter();
sorter.SortColumn = e.Column;
sorter.Order = System.Windows.Forms.SortOrder.Ascending;
lvw.ListViewItemSorter =sorter;
lvw.Sort();
}

c# How do I select a list box item when I have the value name in a string?

I have a string 'item3' and a listbox with 'item1,item2,item3,item4', how do I select item3 in the list box when I have the item name in a string?
Thanks
int index = listBox1.FindString("item3");
// Determine if a valid index is returned. Select the item if it is valid.
if (index != -1)
listBox1.SetSelected(index,true);
listBox.FindStringExact("item3");
Returns the index of the first item found, or ListBox.NoMatches if no match is found.
you can then call
listBox.SetSelected(index, true);
to select this item
Try with ListBox.SetSelected method.
Maybe like this:
public bool SelectItem(ListBox listBox, string item)
{
bool contains = listBox.Items.Contains(item);
if (!contains)
return false;
listBox.SelectedItem = item;
return listBox.SelectedItems.Contains(item);
}
Test method:
public void Test()
{
string item = "item1";
if (!SelectItem(listBox, item))
{
MessageBox.Show("Item not found.");
}
}
SelectedValue will work only if you have set the ValueMember for the listbox.
Further, even if you do set the ValueMember, selectedValue will not work if your ListBox.Sorted = true.
Check out my post on Setting selected item in a ListBox without looping
You can try one of these approaches:
lb.SelectedValue = fieldValue;
lb.SelectedIndex = lb.FindStringExact(fieldValue);
This is a generic method for all listboxes. Your implementation will change based on what you are binding to the list box. In my case it is DataTable.
private void SetSelectedIndex(ListBox lb, string value)
{
for (int i = 0; i < lb.Items.Count; i++)
{
DataRowView dr = lb.Items[i] as DataRowView;
if (dr["colName"].ToString() == value)
{
lb.SelectedIndices.Add(i);
break;
}
}
}
Isn't SelectedValue read/write?
static class ControlHelper
{
public static void SelectExactMatch(this ComboBox c, string find)
{
c.SelectedIndex = c.FindStringExact(find, 0);
}
}
CheckBoxList.Items.FindByValue("Value").Selected = true;

Categories