ListView DrawSubItem Event - c#

I have a ListView control in my windows form. I am adding images to ListView subItems using DrawSubItem event. It seems normal when I populate my ListView. But problem is every time I click ListView, DrawSubItem event fires. Therefore, all images and texts are loading every click and I can't select any item on my ListView. How can I solve this problem?

I have designed Better ThumbnailBrowser component that solves background loading of images and thread synchronization for you, so that you don't have to set images in draw events.
You can also try Better ListView Express, which is free for any kind if usage.
Unlike regular .NET ListView, you can set images of arbitrary sizes in the items.

Related

Not showing items with Visibility=Collapsed in Windows 8.1 GridView

I have a Windows 8.1 application with a GridView bound to a custom (sortable, deduplicated) observable collection. In this collection, I do some heavy filtering and setting an IsHidden flag for every item.
In the data template for the item, there is a condition making the item collapsed if IsHidden flag is set to true.
<Grid Width="160" Height="280" Visibility="{Binding IsHidden, Converter={StaticResource InvertedBooleanToVisibilityConverter}}">
This approach works in Windows Phone 8.1 XAML, making the items disappear from the ListView but it does not work in Windows 8.1 GridView. The problem with Windows 8.1 is that when I set an item in the collection to hidden, id disappears from the GridView but leaves an empty place, so there is a gap in the GridView.
Any ideas on how to solve it? Maybe same XAML style editing?
Here is a minimal solution to reproduce the problem: https://dl.dropboxusercontent.com/u/73642/gv.zip
I tried binding width and height of the items to the hidden flag and setting it to 0 when the item is hidden, but it did not help, still a gap in the GridView.
Update: One workaround would be filtering the actual bound collection, but this is not possible, because of some business requirements.
The problem is in the GridView's ItemsPanel.
Both ItemsWrapGrid and WrapGrid are uniform grids. All their child elements will be sharing the same height and width. That's why even if you collapse the ItemTemplate, the space is still reserved.
What you really need here is a WrapPanel. WINRT doesn't have a built-in WrapPanel but Jerry Nixon has built one and you can grab it from here.
After you updated your GridViews ItemsPanel, you still have one more thing to do. You need to also get the GridViewItem that hosts your Itemtemplate and set its Visibility to Collapsed.
private async void Button_Click(object sender, RoutedEventArgs e)
{
ds[5].IsHidden = true;
await Task.Delay(1000);
var gridViewItem =(GridViewItem)this.gv.ContainerFromIndex(5);
gridViewItem.Visibility = Visibility.Collapsed;
}
I put a little delay above to make the collapsing more obvious.
I tried your sample solution and changed it to a ListView instead. It exhibits the same behavior when the grid itself is hidden. I don't have XAML Spy to verify, but it appears that any List based control will allocate a rendered item for each item in the list.
I changed your click handlder to instead ds.RemoveAt(5); instead of hiding the item, and the element is removed from view with a nice animation. This appears to be as expected, and an interesting find.
It takes me a lot of time to understand the problem, and the solution right in front of my eyes. You trying to hide the item itself but the container still there, When you add an item to an GridView, the item is wrapped in an item container. from msdn :
" When you add an item to an ItemsControl, the item is wrapped in an
item container. For example, an item added to a ListView is wrapped in
a ListViewItem. Without UI virtualization, the entire data set is kept
in memory and an item container is also created for each item in the
data set. A ListView that's bound to a collection of 1000 items will
also create 1000 ListViewItem containers that are stored in memory."
You need to disable the container and create two DataTemplate and using DataTemplateSelector you can choose which DataTemplate for disable and active items. Check this useful article .

updating ListBox colors in C#

for my purposes I am writing a GUI in 4.0 that displays my custom Instance objects in a ListBox with custom colors. I've been able to draw them in their respective colors, but am wondering if there is a way to change these colors.
I've attempted and went down the route of clearing the ListBox and readding the Instance objects in a separate BackGroundWorker every few seconds, but this route has lead to many headaches with the fact that the ListBox.selectedIndex will change and shoot off an event to my ListBox_SelectedIndexChanged event handler. So I would like to avoid that if possible as it is a nightmare to try to code through with threading, locking, raceconditions, turning event handlers on and off, Invalidargumentexceptions.
I was wondering, is there any way for a backGroundWorker to visually update the colors in my ListBox without the need to add and re-add the items to trigger the DrawItem event as described here?
Edit:
Calling ListBox.Refresh() redrew all the items in the listbox, and doing so, avoided the selectedIndexChanged event handler and updated the Colors of all the items
Change the color and call ListBox.Update(), or if from a different thread, ListBox.Invoke(new MethodInvoker( ()=>ListBox.Update() ))
If you have the background worker report progress, then you can in the progress changed method, access the items in your list box and redraw the one you want, depending on what percentage of progress you reported. Should be fairly simple, unless you have a lot of items and a lot of colors.

ListBox not updating

I am using a ListBox in one of the windows form application. When the screen first initializes, I am able to add/remove item into the listbox. However, after I click on one of the buttons to change the content of the listbox, the listbox does not update the values. I tried putting the Listbox inside a Panel and Refreshing the panel to no avail. Anyone ran into same problem?
It sounds as though the data source you are binding to does not support IBindingList.

How do I trap a double-click event on a ListView that has no items?

In my C# app, I have a ListView on a Form. I want the user to be able to double-click on a section of the ListView when no items are selected in order to pop up a "New Item" dialog. The problem is that the DoubleClick event for the ListView only fires if an item is selected.
Is there a way to do this?
There is a way to do this, but you have to do some low-level drilling into the Windows machinery. It's generally not a good idea to spend a great deal of time trying to get a standard Windows control to behave in a non-standard manner.
A simpler way is to just put a "New Item" button next to your ListView. If screen real estate is an issue, you could just add an extra row at the bottom that says "{click here to add new item}", and show your dialog when the user clicks this last row.
Add an event handler for the List view's MouseDoubleClick event.
Assuming Windows Forms:
Perhaps a good workaround would be to use a ContextMenu.

Is there an post Drag and Drop event?

I'm trying to implement drag and drop capability into a custom data grid control. In the end, I'd like to be able to drag rows between 2 of these custom data grids. I believe I have everything working as expected. However, I need to do some cleanup in the drag and drop source control. Specifically, I need to refresh the grids after items are moved. How do I do this? If it make any difference, these grids are not bound to a data source (for other reasons I won't explain).
You supposed to perform post-drop operation on the drag source in the MouseMove event handler after the call to DoDragDrop() returned and on the drop target in the DragDrop event handler.

Categories