Basically, I have a listview inside my form. In order to make the process of selecting the different items in the listview quicker, i have to add a "select all items" checkbox.
For Each lvItem As ListViewItem In Me.lvwDatos.Items
lvItem .Checked = True
Next
That's about it, very simple. Once i click on the select all checkbox, i can see clearly how all the elements go into checked state. However, on the next step, when i want to loop through the selected items in my code and do whatever tasks should be applied to them, i'm finding that ALL elements are unchecked. What's making them loose their state?
Ok, nevermind, i found the problem...that's how it is supposed to be, there's no problem in the listview, it's just the chain of events that were taking place that broke it all...legazy code, as usual...
This is why I have designed Better ListView component which have this behavior fixed (and many other quirks of .NET ListView).
There is also a free Better ListView Express, if you are interested.
The checked item collection is maintained separately and you always get its actual state.
Related
I'm trying to create a wpf control consisting of a list with an element at the end to add a new item (kind of what some grids have). I've been googling around trying to find a similar component but I've found nothing.
I'm new to wpf and willing to write it from scratch if there is nothing similar.
Any ideas will be appreciated.
Thanks!
A DataGrid can do that (does so by default), if your item has no default constructor you can use a BindingList<T> and factory code via the AddingNew event, of course your collection needs to implement IList so items can be added in any case.
For other controls you can also bind them to collection views that support adding, in that case you need to style the NewItemPlaceholder (make it a Button with adding logic for example).
I have a strange problem with a listbox. I added only the listbox and a button which adds items to the listbox. If I click an item in the listbox it seems to have some strange multi selection mode on or something... i recorded a short screen cast, see for your self:
http://www.youtube.com/watch?v=zV4424ipNEA
any ideas whats wrong?
That is a known issue, as all those strings are the same the selection gets confused because they all are essentially the same object. If you create two identical strings in .NET it does not necessarily create a new one but may reuse the first instance, i am not an expert on this though.
Either wrap the strings in a class (make them the Content of a ListBoxItem for example) or make sure the values are unique.
I need a ListBox which will contain several options. I need checkboxes exactly(style), not radio buttons. Is there any way i can allow only 1 checked checkbox at the moment? I'm using MVVM, so i can't just check or uncheck them manually, it's against the rules.
And if i can't make such functionality - is there easy way to style radiobuttons to look like checkboxes?
Aside from a flawed requirement*, the only way to do this is to uncheck all checkboxes, then check the particular indexed checkbox.
Or alternately (cos it does the same thing, but sounds longer), iterate through all the indicated checkboxes and find whichever one is set to true that is not the one you want checked, then set it to false.
flawed requirement: A series of checkboxes indicates to any user that they are allowed to select zero or more items. A series of radiobuttons indicates that they are allowed to select only one. This is something that has been drilled into users since before Windows 3, and that all non-IT will not question. You'll break their mental model, which is worse than looking pretty. Please have management revise this requirement.
HTTH. YMMV.
If you are using MVVM and what to stick to the "rules" then your ViewModel should have a property to which the checkboxes bind. Its the up to code in the ViewModel to ensure that state of this property is correct.
So code in the ViewModel where one property gets set to true may need hunt through a collection to find similar items whose matching property needs to be forced to false. The View then simply reflects the current state of the ViewModel.
Well, in the end, i used this solution
I populate a ListBox control with my own objects redefining ToString(). The objects are displayed correctly when I just add those objects using listBox1.Add(myObject). However, if I later change something in this object, no changes are displayed in the listbox. Debugging reveals that an object inside listBox1.Items is indeed changed, but it is not reflected on a screen.
Interestingly enough, if I reassign a particular listbox item to itself (sounds a bit weird, doesn't it?), like:
listBox1.Items[0] = listBox1.Items[0]
this line will display a correct value on screen.
What is going on here? Does it have anything to do with threading?
Since you're using ToString of the object to provide the text of the list box item, the ListBox has no idea that the value has changed. What you should do instead is have the object implement INotifyPropertyChanged then expose a public property such as Name or Text and return what you normally would have returned from ToString().
Then set the DisplayMember of the ListBox to the name of the new property.
Make sure you are correctly raising the PropertyChanged event in the object and the ListBox should be able to automatically pick up the changes.
Edit: Adrian's edit reminded me that I do believe you'll need to use a BindingList as your data source in order for the property change notifications to be picked up. A quick scan in Reflector looks like ListBox on its own will not pick up the property changes mentioned above. But INotifyPropertyChanged + BindingList should.
The ToString() value of each item is cached when the listbox is first displayed. If an item in the listbox's Items collection then changes, the listbox does not notice and still uses the cached ToString() values for display. To force the listbox to update, either call RefreshItems() to refresh all items, or call RefreshItem(int) specifying the index of the item to refresh.
From the MSDN docs for RefreshItems():
Refreshes all ListBox items and retrieves new strings for them.
EDIT: It turns out that both of these methods are protected, so cannot be called externally. In trying to find a solution, I came across this SO question that this question is basically a duplicate of.
Have you tried calling Refresh() on the ListBox? I think the problem is that the ListBox does not know your object changed. The reason reassigning the the item works is because the ListBox will repaint itself when the collection changes.
you could invalidate the control, forcing a re-paint... perhaps..
I'm using a TreeView to let the user navigate a complex data structure more easily. I'm trying to add a feature to my application so my users can add new items to the datastucture by clicking a button on a toolbar. This new item has 3 levels, each with 1 item. I would like to select the item in the lowest level.
Adding the data isn't a problem, I just add a new item to the collection that is bound to the TreeView in a specific. I can lookup the item by hand browsing the TreeView, so I know the adding works. Now, I want to set the selection of the new item programmaticly. So the user can change the default settings in the element right away.
I've done some testing and I've found that setting the selection is done with something like:
var obj = TreeView.ItemContainerGenerator
.ContainerFromItem(selectedObject) as TreeViewItem;
obj.IsSelected = true;
I've tried adding this code directly after my Add-method. The adding function returns the new object and places this in selectedObject. The Add-method adds a to an ObservableCollection, which raises the appropriate events.
But, obj is always null directly after adding.
I've tried setting the selection in the LayoutUpdated event, but in this case the obj variable from the earlier code always null again.
I think I might be missing something here. Does anyone have an idea on how to add a new item to the bounded collection and select that item in the TreeView?
You might want to read this article by Josh Smith on using the treeview in WPF. He demonstrates how to use an IsSelected property that could easily be adapted for your needs, using the MVVM pattern.