I have a piece of code that will add the selected item of a combobox to a listbox when a checkbox is checked. I would like to remove that selected item to be removed from the listbox when the checkbox is unchecked.
My problem is I cant simply repeat the code for removal to be the same as add because the combobox selection will different or empty when unchecked.
This is how it currently looks:
private void CBwasher_CheckedChanged(object sender, EventArgs e)
{
if (checkBox1.Checked == true)
{
listBox2.Items.Add(comboBox1.SelectedItem);
}
if (checkBox1.Checked == false)
{
listBox2.Items.Remove(comboBox1.SelectedItem);
}
So I need a way of removing whatever was added by that check change instead of removing the selected index of the combobox. Please consider that there may be multiple lines in the listbox added by multiple different checkboxes.
You simply need to store the added item and remove it.
private object addedItem;
private void CBwasher_CheckedChanged(object sender, EventArgs e)
{
if (checkBox1.Checked)
{
addedItem = comboBox1.SelectedItem;
listBox2.Items.Add(addedItem);
}
else
{
listBox2.Items.Remove(addedItem);
}
}
You may also need to check SelectedItem is null before adding/removing the item.
Focusing on the part where you said there might be multiple different checkboxes,
you need to store one item per checkbox.
You can write your own child class of the checbox control to add this feature, or simply use the Tag property.
You can also indicate which checkbox is linked to which combobox in the same way. Either child class or use the Tag property.
In my example, I'll assume you've referenced the combobox from the checkbox using the Tag property.
You can do it manually like this
checkBox1.Tag = comboBox1;
or hopefully you can automate it if you are generating these on the fly.
Here is the general idea of how the checkbox event should look.
The event is is utilising the sender argument, which means you should hook up all your checkboxes CheckedChanged events to this one handler. No need to create separate handlers for each.
private void CBwasher_CheckedChanged(object sender, EventArgs e)
{
var checkBox = (CheckBox)sender;
var comboBox = (ComboBox)checkBox.Tag;
if (checkBox.Checked && comboBox.SelectedItem != null)
{
listBox2.Items.Add(comboBox.SelectedItem);
comboBox.Tag = comboBox.SelectedItem;
}
if (!checkBox.Checked && comboBox.Tag != null)
{
listBox2.Items.Remove(comboBox.Tag);
}
}
Related
I am a student learning xamarin forms, I am trying to create a basic chat app in this I want to know how to get position of current item in listview that's user watching. When a new message received i want to know if user is at bottom or not if at bottom focus the new and if not at the bottom then just add not by adding focus to it.
you get the selected item from the Xamarin.Forms.ListView.SelectedItem property of your ListView.
If your ListView.ItemSource is of a type that allows using IndexOf you can now do something like
int position = (yourlistview.ItemSource as ObservableCollection<your type>).IndexOf(yourlistview.SelectedItem)
Update:
ok I think i understood what you want.
In most cases more than one item is currently shown when using a listview. So their exists not a single index
but i think you just want to know if the last item of the list is visible/the user has scrolled to the end?
If so ListView has an ItemAppearing event. I use it for example to load more data from an websource if the user scrolled through the first 100 items.
You could do something like this
listview.ItemAppearing += listviewItemAppearing;
listview.ItemDisappearing += listviewItemDisappearing;
bool m_scrolledToEnd;
private void listviewItemDisappearing(object sender, ItemVisibilityEventArgs e)
{
if(e.Item == yourlastiem)
m_scrolledToEnd = false;
}
private void listviewItemAppearing(object sender, ItemVisibilityEventArgs e)
{
if(e.Item == yourlastiem)
m_scrolledToEnd = true;
}
if you realy need to know if a specific index is shown you could create a List<int> m_idxlist;
and in the appearing event add the index of the item to the list
and in the disappearing event remove the index of the item from the list.
Then you will have a list where all indexes of the items currently shown are stored.
From the Documentation
ListView supports selection of one item at a time. Selection is on by
default. When a user taps an item, two events are fired: ItemTapped
and ItemSelected. Note that tapping the same item twice will not fire
multiple ItemSelected events, but will fire multiple ItemTapped
events. Also note that ItemSelected will be called if an item is
deselected.
To detect selecting an item, you can add a method, onSelection:
void OnSelection (object sender, SelectedItemChangedEventArgs e)
{
if (e.SelectedItem == null) {
return; //ItemSelected is called on deselection, which results in SelectedItem being set to null
}
DisplayAlert ("Item Selected", e.SelectedItem.ToString (), "Ok");
//((ListView)sender).SelectedItem = null; //uncomment line if you want to disable the visual selection state.
}
To disable selection just set the selectedItem to null:
SelectionDemoList.ItemSelected += (sender, e) => {
((ListView)sender).SelectedItem = null;
};
I have five RadioButton and five ComboBox controls.
Each RadioButton is connected to a ComboBox.
When I activate one RadioButton, the corresponding ComboBox, it gets enabled.
Now when I choose another RadioButton, the information in the previously selected ComboBox should clear but does not!
I have tried with ComboBox.Clear() as well as ComboBox.Reset(), but it doesn't work.
Here is my code for one of the ComboBox and RadioButton
if (radioButtondinner.Checked == true)
{
comboBoxdinner.DataSource = DList.Dwork();
comboBoxdinner.DisplayMember = "dinner";
}
As I said in comment: you can use one Combobox and only to change data sources when you check other RadioButton that should work sure
But If you want to have more Combobox then just type in else statements
comboBox.DataSource = null;
// create a check change event and use this.
private void radioButtondinner_CheckedChanged(object sender, EventArgs e)
{
if (!radioButtondinner.Checked)
{
// if you want to clear only the text or selected item text
comboBoxdinner.Text = String.Empty;
// if you want to clear the entire data source
comboBoxdinner.DataSource = null;
}
}
Is there a way to check to see which combobox which value has been most recently changed?
how to check if item is selected from a comboBox in C#
I know you can do this,
if (MyComboBox.SelectedIndex >= 0)
{
//do stuff
}
The problem I am having is that I am combining Event Handlers in to one handler due to the amount of comboboxes and having one event for each combobox really is not practical if I can help it.
Is there a way to have a variable assigned giving you the name of the combobox which value has been most recently changed? Or will I have to use individual event handlers for each combobox?
Actually It will be very easy to track most recent combobox change when you using single event handler for all combobox. You can do by following way.
string lastComboName=""; // define global variable
//common event handler for all combobox
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var cmb = (ComboBox)sender;
lastComboName = cmb.Name;
}
Hope that each comboBox having an unique name, then we can use those name to identify which one is the sender of event: Now consider the following code for this:
private void CboFirst_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ComboBox selctedComboBox = sender as ComboBox;
string ComboName = selctedComboBox.Name;
// Do something
}
Now tracking the last updated ComboBox, You can achieve this by keeping a blobal variable and update it in every trigger so Every time it holds the Latest value( the name of the combobox)
Okay, so I have four listBox controls. I want to select the same index on all four listBox when one item is clicked on any of them. To be mentioned, I do change the index sometimes in the program. I tryed using a method listSelectChange (int index) and adding for each listBox an event for selectIndexChange, but it would activate the event even if the select is made by the program and not by user-control.
Please don't use classes, just a brute method would be fine!
You can unsubscribe from selectedIndexChanged before you update the ListBox and re-subscribe to it immediately after that. It's a common practice.
Since you gave no code example I'm doing some guessing here.
// Enumerable of all the synchronized list boxes
IEnumerable<ListBox> mListBoxes = ...
...
public void OnSelectedIndexChanged(object sender, EventArgs e) {
var currentListBox = (ListBox)sender;
// Do this for every listbox that isn't the one that was just updated
foreach(var listBox in mListBoxes.Where(lb => lb != currentListBox)) {
listBox.SelectedIndexChanged -= OnSelectedIndexChanged;
listBox.SelectedIndex = currentListBox.SelectedIndex;
listBox.SelectedIndexChanged += OnSelectedIndexChanged;
}
}
I have dozens of list boxes on my form. I want to be able to edit/delete items from those list boxes using only one edit button and only one delete button. Should a loop be created so I don't have to code an if statement for each list box? Maybe a custom method? Kind of lost here.
Thanks for the input.
This is the code for one of the list boxes to for edit:
private void btnEdit_Click(object sender, EventArgs e)
{
//Edit an item in the list box
//If there are no appointments OR no appointment is selected, inform the user and cancel the operation
if ((!(appointmentList.Count > 0)) || lstDayView.SelectedIndex == -1)
{
MessageBox.Show("Error! You need to select an appointment!");
return;
}
else
{
int index = lstDayView.SelectedIndex;
var myForm = new Form2(appointmentList[index] as Appointment);
if (myForm.ShowDialog() == DialogResult.OK && myForm.Tag is Appointment)
{
Appointment appoint = myForm.Tag as Appointment;
//lstDayView.Items.RemoveAt(index);
appointmentList.RemoveAt(index);
appointmentList.Insert(index, appoint);
//appoint.toListBox(lstDayView, index);
this.setCal();
}
}
And this is for delete:
private void btnDeleteApp_Click_1(object sender, EventArgs e)
{
if ((!(appointmentList.Count > 0)) || lstDayView.SelectedIndex == -1)
{
MessageBox.Show("Error! You need to make and/or select an appointment!");
return;
}
else
{
if (MessageBox.Show("Are you sure you wish to delete?", "Confirm Delete", MessageBoxButtons.OKCancel) == DialogResult.OK)
{
appointmentList.RemoveAt(lstDayView.SelectedIndex); //Issue this is removed the index number from the list not the appointmentList
this.setCal();
}
}
As ThunderGr suggests, you can attach the same event handler to all Listboxes so that the same logic can be applied. When it comes to iterating (both to assign the event handlers initially, and to subsequently work on the collection as a whole), I would set the Tag property of each control to something relavent (e.g. "List"), and then you can do:
foreach(var control in Controls.Where(c => c.Tag == "List"))
{
// work with control here (casting to ListBox appropriately).
}
You could even make this a method of your form that returns IEnumerable<ListBox> like this:
public IEnumerable<ListBox> ListBoxes
{
get
{
return Controls.Where(c => c.Tag == "List").Cast<ListBox>();
}
}
You are removing another ListItem (lstDayView) from appointmentList List.
Replace This :
appointmentList.RemoveAt(lstDayView.SelectedIndex);
With following :
appointmentList.RemoveAt(appointmentList.SelectedIndex);
You can use the Form.Controls collection in a foreach loop to check for and manipulate the listboxes.
Another thing you can do is to assign the same selectedindexchanged event to all the listboxes you want to manipulate. The "sender" parameter holds the object that caused the event to fire. You can cast it to a listbox and manipulate it.
EDIT:Your basic problem is that you do not know which listbox was last selected. You need to define a variable that will keep the last listbox entered by the user(using the Enter event) and use that variable to delete the item from the listbox.
Example:
ListBox lastEnteredListbox = null;
private void aListboxName_Enter(object sender, EventArgs e)
{
lastEnteredListbox=(ListBox)sender;
}
private void theButton_Click(object sender, EventArgs e)
{
if(lastEnteredListbox == null || lastEnteredListbox.SelectedIndex == -1)
{
MessageBox.Show("You need to select an Item");
return;
}
lastEnteredListbox.RemoveAt(lastEnteredListbox.SelectedIndex);
}
You need to set the Enter event of all listboxes you wish to manipulate to the aListBoxName_Enter method.
In case that you want to simply delete the same index from all listboxes, you just loop through the controls collection of the form and do an if(control is ListBox) ((ListBox)control).RemoveAt(index);