WPF Deleting item from listbox - c#

I have a listbox in WPF that's bound to a ObservableCollection using the ItemSource property. This works fine, the correct items are shown.
The listbox (which contains a list of image names) has an event handler on the SelectionChanged event which updates the source of an Image control with the path to the selected image (effectively giving an image preview).
I have the following code to remove an item from the lisbox, on a button's click event:
if (lstLocal.SelectedIndex > -1)
{
localImages.RemoveAt(lstLocal.SelectedIndex);
}
localImages being the ObservableCollection and lstLocal being the ListBox.
However, when I remove the selected item this causes the SelectionChanged event to fire. My SelectionChanged event handler makes use of the SelectedIndex property on the listbox. I get the exeption Index was out of range. Must be non-negative and less than the size of the collection. , so I'm guessing that removing an item causes SelectedIndex to be set to something like null (or a negative number)?
Is there a way around this problem? I'm guessing there's a better way for me to remove items, or I need some sort of check on my SelectionChanged handler?

Wrap the code in your SelectionChanged handler in a
if (lstLocal.SelectedItem != null)
{
...
}

Ah, a classic annoyance of the ListBox control. When altering the bound collection, it can clear the selection and reset the scroll position to the top. It's truly irritating when you have to select items from a list and edit them piecemeal as part of a workflow.
You may want to maintain a "currently selected item" object reference when changing the list so that you can keep the selection if something changes behind the scenes. Then you can also make sure that if it exists, that it stays in view by scrolling back to that item using the ScrollIntoView method.
A SelectedIndex of -1 means nothing is selected, as you have already remembered. This is an ancient hold-over from pre-.NET, before the SelectedItem property existed. Nowadays SelectedItem will be null at the same time as SelectedIndex is -1.

Related

UWP: Raise Key Down programmatically

I want to manage the listview while the text field is in focus. I mean the following case: I'm writing some text into the text box, but I am able to manage the list view selection in the same time by some keys(Up, Down).
I tried to change the SelectedIndex property, but I lose the automatic scrolling of the list view in this case.
I think it could be solved by raising key down event with a special key (Up, Down) for the listview - is there any way to do it?
you just need to use ScrollIntoView() method of ListView whenever you set the SelectedIndex of your ListView just follow it up with ScrollIntoView. you do it in 2 ways.
subscribe to SelectionChanged event and scroll the new selected item into view.
instead of setting SelectedIndex you can set SelectedItem and then scroll that item into view.
After setting the SelectedIndex, just get the item of that index and then scroll that item into view.

ComboBox reverting to index 0 at seemingly random

I have an array of ComboBoxes, each with it's own DataSource which is set at the beginning and not messed with any further. Each ComboBox has some index (which is not 0) selected.
Now, I have a grid of Panels drawn on a Form. Each Panel is connected to it's own ComboBox. According to set rules, ComboBox can be drawn on the Form. Here are the rules:
On mouseClick connected-ComboBox is designated as selected-ComboBox. It was already drawn on mouseEnter event.
On mouseEnter selected-ComboBox is replaced with the connected-ComboBox.
On mouseLeave connected-ComboBox is replaced with selected-ComboBox.
Basically, it displays the last selected ComboBox, or the one you are currently hovering over.
When I started the program and started hovering my mouse above the Panels, different ComboBoxes were displayed. However, after some seemingly random time, their index will change to 0, displaying the item at said index.
Now, I only change the selectedIndex of the ComboBox in one place in my code, and that spot should not be executed during the test - and it is not, proven by placing a breakpoint that never triggers.
I can change the selectedIndex as the user using the ComboBox - but I don't do that, so that's out. I just hover over the Panels.
I managed to pause the program after it happened to examine the state of the altered ComboBox. SelectedItem, SelectedIndex and Text properties were all changed. The interesting part? SelectedIndexChanged event never fired.
I don't think this has to do anything with the code, but is some kind of strange behaviour of ComboBox.
What are the reasons for which the ComboBox might default to first index as selected one, not firing the SelectedIndexChanged in the process?
If nothing else, is there a way I could monitor the SelectedIndex property of the ComboBox in a way the code pauses if it changes (as though there was a breakpoint in the setter)?

WPF Listbox item information

For each item in my listbox, I have a Button and a TextBlock. I can set my button to raise an event that removes an item from the ListBox, if I click on the TextBlock to highlight the item and then Remove(myListBox.SelectedItem).
However, I'm looking for a way to identify which item in the ListBox a specific Remove-Button is attached to, so I can RemoveAt(?) when the event is raised.
Edit: Each of the buttons should remove the item on the line of that button without highlighting the line first. Therefore, using ListBox.SelectedItem is not a viable option :)
You can get the index of the item using the IndexOf method:
YourCollection.RemoveAt(YourCollection.IndexOf(myListBox.SelectedItem));

C#(Winforms) Databinding using Listbox.SelectedValue as data source (master-detail)

I have a listbox bound to a List<object> as its DataSource. What I'm wanting to do is use the SelectedValue property of the Listbox (i.e the object corresponding to the current selection) as a DataSource for some textboxes that will display certain values of the object for editing.
I've tried
TextBox.DataBindings.Add(new Binding("Text", ListBox, "SelectedValue.name"));
and
TextBox.DataBindings.Add(new Binding("Text", ListBox.SelectedValue, "name"));
but as there is nothing selected in the ListBox (because the form hasn't been shown yet), I get an exception about "Value cannot be null".
Now I know that I can (re)bind to ListBox.SelectedValue in my form's SelectionChangeCommitted handler (that is, after a selection has been made), but if i have to do that I might as well just set the TextBox's value directly (admittedly I could just do this to resolve the issue, but I'd like to learn more about databinding).
So my question is, in short: Is it possible to bind to ListBox.SelectedValue once (initially, before the ListBox has a selection) and avoid the null value exception, and if so, how?
I'm not sure which control your projectNameCtrl is, but you'll want to bind your TextBox. Something like this:
textBox1.DataBindings.Add(new Binding("Text", listBox1, "selectedvalue"));
Where:
textBox1 is your TextBox
listBox1 is your ListView
EDIT
You should be able to data bind a ListBox even if that ListBox has no selected items so your 'value cannot be null' must be for another reason. I suggest using the debugger to determine which object specifically is null.
You can ensure you don't data bind a control more than once by first checking the control's DataBindings.Count property; if it's equal to zero you haven't yet data bound that control:
if (textBox1.DataBindings.Count == 0) {
// OK to data bind textBox1.
}
Off the top of my head, I think you'd need to do something on each selectedItemChanged event...
I know this doesn't answer your question, but I'd look at using WPF instead since this is so much more elegant to do in WPF, and let's face it, by not creating a GUI in code (using XAML instead) your sanity will be much more intact when you finish your project. I don't recall enough windows forms, but in WPF, you just implement INotifyPropertyChanged on your back-end object that you're binding to, and then when you bind to the SelectedItem property of that ListBox, you automatically get updates since the SelectedItem property is a DependencyProperty.

Scrolling to the Previously Selected ListBox item

I am having trouble setting the Selected Item of a Listbox I am populating and adding to the LayoutRoot's children in code.
I am creating the ListBox over when going back to the page, so I am saving a variable which will tell me what the selected item was before the user clicked.
I tried setting SelectedIndex, but that did not seem to work. That selects the item and calls SelectionChanged, but the item does not come into focus.
I also tried the combination of MyListBox.ScrollIntoView(MyListBox.Items[MyListBox.SelectedIndex]) and MyListBox.UpdateLayout(), but that did not seem to work either. The item does not seem to come into focus.
Try MyListBox.SelectedItem.EnsureVisible().
(If it doesn't have SelectedItem (ListBox on the desktop CLR doesn't), then use SelectedItems[0] instead)
E: Okay, looks like Windows Phone doesn't support that. However, it does support MyListBox.EnsureVisible(MyListBox.SelectedItems[0])
I ended up fixing this by Adding the UserControl that had the ListBox into the Page's XAML, and the ListBox into the UserControl's XAML.
Then, I was able to use the ScrollIntoView(MyListBox.Items[mySavedSelectedItem]);
I simply saved this value when the user made the selection.
mySavedSelectedItem = ((ListBox)sender).SelectedIndex;

Categories

Resources