How to sync selection index between two ListBoxes - c#

I have two listboxes: listBox1, listBox2.
If i select the item in first listBox1, item of the same index must be automatically selected in listBox2.
So, If i select item 1 in listbox1 then, item 1 selected automatically in listbox2 and so on.
Not: I found some examples but not work.
private void listBoxControl2_SelectedIndexChanged(object sender, EventArgs e)
{ listBoxControl5.SelectedIndex = listBoxControl2.SelectedIndex; }
Edit:
I solved it using the selected index code in This answer in SelectedValueChanged Event.
private void listBoxControl2_SelectedValueChanged(object sender, EventArgs e)
{
listBoxControl5.SelectedIndex = listBoxControl2.SelectedIndex;
}

Here's a sample that you may want to explore more, try to add ListBoxto your form (in this sample 3 listboxes) it should look like the following:
And here's the source that would select the same index whenever you click on an item on it:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
InitializeListBoxes();
}
private void InitializeListBoxes()
{
//Populate listboxes
listBox1.Items.Add("Apple");
listBox1.Items.Add("Orange");
listBox1.Items.Add("Mango");
listBox2.Items.Add("Milk");
listBox2.Items.Add("Cheese");
listBox2.Items.Add("Butter");
listBox3.Items.Add("Coffee");
listBox3.Items.Add("Cream");
listBox3.Items.Add("Sugar");
//Subscribe to same events
listBox1.SelectedIndexChanged += listBox_SelectedIndexChanged;
listBox2.SelectedIndexChanged += listBox_SelectedIndexChanged;
listBox3.SelectedIndexChanged += listBox_SelectedIndexChanged;
}
void listBox_SelectedIndexChanged(object sender, EventArgs e)
{
ListBox listBox = (ListBox)sender;
listBox1.SelectedIndex = listBox.SelectedIndex;
listBox2.SelectedIndex = listBox.SelectedIndex;
listBox3.SelectedIndex = listBox.SelectedIndex;
}
}
What happens is on the InitializeListBoxes you subscribe to the same event which would trigger the SelectedIndexChanged event, and select appropriate item from each of the ListBox.

to solve your problem, you can use a pattern called Observer: https://msdn.microsoft.com/en-us/library/ee850490(v=vs.110).aspx
Basically, you will have to create a notifier method in the listboxes that you want to notify. When you select an item in listBox1, you will call the notifier method of listBox2.

I solved it using the selected index code in This answer in SelectedValueChanged Event.
private void listBoxControl2_SelectedValueChanged(object sender, EventArgs e)
{
listBoxControl5.SelectedIndex = listBoxControl2.SelectedIndex;
}

Fastest and easiest way can be via MouseDown event:
private void lstBoxes_MouseDown(object sender, MouseEventArgs e)
{
ListBox lstBox = (ListBox)sender;
lstBx1.SelectedIndex = lstBox.SelectedIndex;
lstBx2.SelectedIndex = lstBox.SelectedIndex;
lstBx3.SelectedIndex = lstBox.SelectedIndex;
}

Related

ListBox SelectedIndexChanged event not fired when bound list updates

I'd like to have a basic ListBox with associated Add and Delete buttons. The Delete button be enabled if and only if there is a selection in the ListBox, and the Add button should append an item to the end of the ListBox.
My first attempt was to just make a List<string> items field, like so:
public partial class Form1 : Form {
public Form1 {
InitializeComponent();
this.listBox1.DataSource = this.items;
}
private void addButton_Click(object sender, EventArgs e) {
this.items.Add("item {this.items.Count + 1}");
}
private void deleteButton_Click(object sender, EventArgs e) {
this.items.RemoveAt(this.listBox1.SelectedIndex);
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e) {
this.deleteButton.enabled = (this.listBox1.SelectedIndex != -1);
}
List<string> items = new List<string>();
}
But, it turns out that the ListBox does not seem to update automatically as the items in the list change. Here's a related question about it.
Most advice suggested just running listBox1.DataSource = null; this.listBox1.DataSource = this.items; every time I updated the list, but that to me defeats the purpose of binding.
Another answer suggested using an ObservableCollection for my list's data type, but that did nothing different.
Finally I found the BindingList class and it seemed to do what I want; the ListBox automatically reflects the contents of the items field. (If there is another solution that is actually a best practice and not some piece of cargo cult folklore pasted around the Internet, please let me know.)
However, when the first item I add to items appears in the ListBox, the row becomes selected. And I can see that listBox1.SelectedIndex changes from -1 to 0. But, the listBox1_SelectedIndexChanged event does not fire. Hence, the state of the Delete button doesn't get updated properly.
(As an aside, this UI pattern is extremely commonplace, and it seems disastrous that there's so much conflicting information on implementing such a simple thing.)
I also ran into the same problem. Since this was the first question I came across, maybe my answer will save someone some time.
When DataSource is assigned an empty BindingList and items are added to that BindingList later, like so:
private BindingList<MyType> _myList = new BindingList<MyType>();
public MyForm()
{
listBox1.DataSource = _myList;
}
private void LoadData()
{
foreach (MyType item in GetDataFromSomewhere())
{
_myList.Add(item);
}
}
then after adding the first item, that will be selected in the ListBox, and listBox1.SelectedIndex will be 0 - but the SelectedIndexChanged event will not have been fired.
Looks like this could be a bug in ListBox as suggested here and here.
A workaround could be to derive from ListBox as Juan did, or just check if the BindingList contains any items before adding:
bool isFirstItem = (0 == _myList.Count);
_myList.Add(item);
if (isFirstItem)
{
// Your choice: set listBox1.SelectedIndex to -1 and back to 0,
// or call the event handler yourself.
}
Try manually selecting the last element, instead of relying on the default behavior. This will trigger the event.
public partial class Form1 : Form
{
BindingList<string> items = new BindingList<string>();
public Form1()
{
InitializeComponent();
this.listBox1.DataSource = items;
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
this.deleteButton.Enabled = (this.listBox1.SelectedIndex != -1);
}
private void addButton_Click(object sender, EventArgs e)
{
this.items.Add($"item {this.items.Count + 1}");
this.listBox1.SelectedIndex = -1;
this.listBox1.SelectedIndex = this.listBox1.Items.Count - 1;
}
private void deleteButton_Click(object sender, EventArgs e)
{
this.items.RemoveAt(this.listBox1.SelectedIndex);
}
}

On listbox double click open new form

Im using windowsForms c# have a listbox which is bound with data items ...So depending on double click of the listbox item i want the corressponding form open...thnx in adv
ListBox has an DoubleClick event. You can access it if you select object, open Events tab in a Properties window.
Double click it and Visual Studio will create an event handler for you like this:
public void ListBox1_OnDoubleClick(object sender, EventArgs e)
{
// here is your code
}
Now, you just need to enter your code.
If you want to open a form with a corresponding item then it will be something like:
public void ListBox1_OnDoubleClick(object sender, EventArgs e)
{
string text = listBox1.Text; // Don't forget to manipulate with it
Form1 form = new Form1();
form.Show();
}
Subscribe to DoubleClick event on ListBox
listBox1.DoubleClick += new System.EventHandler(this.listBox1_DoubleClick);
private void listBox1_DoubleClick(object sender, EventArgs e)
{
// logic here
}
or
listBox1.DoubleClick += (s,e) => { /*logic here */};
I would use the MouseDoubleClick Event, it provides the cursor position in MouseEventArgs so you can easily detect which item got doubleclicked.
void Listbox1_MouseDoubleClick(object sender, MouseEventArgs e)
{
int index = Listbox1.IndexFromPoint(e.Location);
if (index != ListBox.NoMatches)
{
object clickedItem = Listbox1.Items[index];
// open your form here
}
}

DoubleClick on a row in ListView

Is there any possibility to get a value of doubleclicked row in ListView?
I registered an event:
private void lvLista_DoubleClick(object sender, EventArgs e)
{
MessageBox.Show(lvLista.SelectedItems.ToString());
}
But on message, when i doubleclick some row in listview i get:
System.Windows.Forms.ListView+SelectedListViewItemCollection
What is more, I have got 2 columns in listview:
lvLista.Columns.Add("ID");
lvLista.Columns.Add("Tilte");
And i want to show in messagebox the "ID" of doubleclicked row.
How to do it? How to get a values from this event?
If you handle the MouseDown and/or MouseDoubleClick events of the ListView control, and use the HitTest method to determine the target of the mouse action, you will know which item has been double clicked. This is also a good means to determine if NO item was clicked (for example, clicking on the empty area in a partially filled list.
The following code will display the clicked item in a textbox if a single click occurs, and will pop up a message box with the name of the double-clicked item if a double click occurs.
If the click or double click occur in an area of the list view not populated by an item, the text box or message box inform yopu of that fact.
This is a trivial example, and depending on your needs, you will have to mess with it a little.
UPDATE: I added some code which clears the SelectedItems property of the Listview control when an empty area of the list is clicked or double-clicked.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
listView1.MouseDown += new MouseEventHandler(listView1_MouseDown);
listView1.MouseDoubleClick += new MouseEventHandler(listView1_MouseDoubleClick);
this.Load += new EventHandler(Form1_Load);
}
void Form1_Load(object sender, EventArgs e)
{
this.SetupListview();
}
private void SetupListview()
{
ListView lv = this.listView1;
lv.View = View.List;
lv.Items.Add("John Lennon");
lv.Items.Add("Paul McCartney");
lv.Items.Add("George Harrison");
lv.Items.Add("Richard Starkey");
}
void listView1_MouseDoubleClick(object sender, MouseEventArgs e)
{
ListViewHitTestInfo info = listView1.HitTest(e.X, e.Y);
ListViewItem item = info.Item;
if (item != null)
{
MessageBox.Show("The selected Item Name is: " + item.Text);
}
else
{
this.listView1.SelectedItems.Clear();
MessageBox.Show("No Item is selected");
}
}
void listView1_MouseDown(object sender, MouseEventArgs e)
{
ListViewHitTestInfo info = listView1.HitTest(e.X, e.Y);
ListViewItem item = info.Item;
if (item != null)
{
this.textBox1.Text = item.Text;
}
else
{
this.listView1.SelectedItems.Clear();
this.textBox1.Text = "No Item is Selected";
}
}
}
Try this:
private void lvLista_DoubleClick(object sender, EventArgs e)
{
MessageBox.Show(lvLista.SelectedItems[0].SubItems[0].Text);
}
I know this thread is old but nobody here answered the question properly in my opinion. For those in the future, try this, from MSDN:
// User must double-click to activate item
myListView.Activation = System.Windows.Forms.ItemActivation.Standard;
// Add event handler
myListView.ItemActivate += new
System.EventHandler(this.myListView_ItemClick);
Since the accepted answer didn't help me i thought that I would share my solution to the same problem: getting data from a specific column in a listview in the double click event.
The following line returns the data of the second column in the row that I've double clicked on as a string:
private void listViewOutput_DoubleClick(object sender, EventArgs e)
{
string content = listViewOutput.Items[listViewOutput.SelectedIndices[0]].SubItems[1].Text
}
Thanks; this is what I needed. I thought I'd also mention one could set up the local info variable more generally as:
ListViewHitTestInfo info = ((ListView)sender).HitTest(e.X, e.Y);
Try this
private void listView1_MouseClick(object sender, MouseEventArgs e)
{
ListViewHitTestInfo hit = listView1.HitTest(e.Location);
Rectangle rowBounds = hit.SubItem.Bounds;
Rectangle labelBounds = hit.Item.GetBounds(ItemBoundsPortion.Label);
int leftMargin = labelBounds.Left - 1;
string x = hit.Item.Text;
}

First mouse click event on an item in a listbox doesn't trigger the function

I am trying to do something like: when a user select an item on a listbox, then the function listboxClicked will be triggered. However, the first click often does not able to trigger the function. It only triggers the function when I click the same item or another item for the second time.
May I know what's wrong with my code? Thank you.
My Code:
private void listbox_SelectedIndexChanged(object sender, EventArgs e)
{
listbox.MouseClick += listboxClicked;
}
private void listboxClicked(object sender, EventArgs e)
{
if (listbox.SelectedIndex != -1)
{
//do something
}
}
Try this one:
Listbox1_SelectedValueChanged(object sender, EventArgs e)
{
Listbox listbox = (Listbox)sender;
MessageBox.Show(listbox.SelectedItem.ToString());
}

selected item change ComboBox

Is there any way to prevent changing the selected item in a ComboBox only if for certain conditions? I want to allow update the selected item's displayValue in the ComboBox. But I don't want user to change the selected item when it's being updated. This is a windows application.
Inside your class:
private int _selectedIndex = 0;
Inside your form load method:
comboBox1.Enter += new EventHandler(comboBox1_Enter);
comboBox1.SelectedIndexChanged += new EventHandler(comboBox1_SelectedIndexChanged);
Then the rest of the code:
protected void comboBox1_SelectedIndexChanged(object sender, EventArgs e) {
if (true) { // Add your validation or certain condition here.
(sender as ComboBox).SelectedIndex = _selectedIndex;
}
}
protected void comboBox1_Enter(object sender, EventArgs e) {
_selectedIndex = (sender as ComboBox).SelectedIndex;
}
Try setting set the Enabled property to false. (Or some third-party toolkits like Telerik have a ComboBox with a ReadOnly property.)

Categories

Resources