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.
Related
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.
I have this idea in my head for an equalizer-like control, but I'd like to be able to do multiselection of the various thumbs and move them all at once. I thought of using a listbox and using the selection property it has but I haven't quite worked out how I'd be able to pass that down into the sliders and move them all in unison. Does anyone have any good ideas or has seen something like this done before?
Presumably you have some control that the user interacts with. One idea would be to create adorners around those controls to show "selected" state. Listen in on the mouse clicks for each of those controls and test the Ctrl modifier (Ctrl and/or shift, both are commonly used for multiple selection). Toggle the selected state of each of them which you'll store in a separate collection (an array perhaps).
When you detect movement on one of these controls, check to see if it's selected. If it is, move all the others.
maybe you can use the SelectedItems property of the Listbox in MultiExtended selection mode.
you bind it to an Observablecollection
then you check the slider's valueChanged event and in the eventhandler you get the difference and increment all the sliders' values in the collection.
now when you select and drag a slider's thumb it will affect other selected sliders.
(minor question: are you using MVVM?)
I am having a collection bound to a WPF ListBox, I want to make the listboxItems aprear one after the other one first binding to the data. To have an effect similar to powerPoint one.
Two options spring to mind:
A. create a storyboard that animates opacity, and apply it to the ItemTemplate
B. use a timer on a background thread to add items one-by-one to the bound collection
Couldn't you just use a timer and add the items to the collection one by one, raising a property changed event in between?
I know this may seem like an odd question, but I am after the information queried in the title.
So far I have tried LayoutRoot.Loaded, but found that LayoutRoot.LayoutUpdated happens even later.
My motivation for this knowledge is the ability to have one component interact with another in code, but for this to happen I must be guaranteed they both exist.
Any ideas?
Clarification of what I'm attempting to do:
I have a collapsing gridsplitter control. From here
When the main page loads I make it collapse; which shrinks the object preceding it to width 0. If that object isn't 'loaded' yet then it doesn't collapse and the gridsplitter is in an odd state where it thinks it has collapsed the item but needs two clicks to effectively do that.
LayoutUpdated is the last event raised in the control object initialization timeline. However keep in mind that LayoutUpdated will be raised multiple time subsequently as required. Maybe you can share a little more detail on what you are trying to do.
I have a wpf application that populates an Infragistics XamDataGrid by the usual method of binding an observable collection to the grid. As each data item is populated into the collection, one at a time, the grid updates. I also have a cancel button that I would like to immediately stop the population if the user clicks it. However, it takes a few seconds or more to respond to the cancel.
The problem (I think) is that the message loop is full of the grid population events and my cancel is way in the back and must wait its turn. I was wondering if there is a way to insert a message in the front of the queue and thus make the cancel more responsive (hacky or not - if hacky, please explain what ill effects I can expect).
I am not experiencing bad performance; in fact the UI is quite responsive. The problem is purely that the cancel event has to wait its turn in the message queue and I would rather it have priority over the population messages.
edit: clarifications
When you say Grid, what kind of Grid do you mean? I think your issue might be that for a large collection, this setup might not use any type of item virtualization. You might be better off using a ListBox or ListView in this case, which can use a VirtualizingStackPanel to generate UIElements for only the on-screen items.
If this is the case, your ui thread is getting bogged down because its generating elements for every new item, whether or not it's being displayed on screen. If you're using a 3rd party Grid, you might check to see if it has any virtualization functionality built in that you can turn on.
The answer ended up being the DispatcherPriority:
private void btnCancel_Click(object sender, System.Windows.RoutedEventArgs e)
{
Dispatcher.Invoke(new Action(() => btnCancel.Command.Execute(null)), DispatcherPriority.Send);
}
"Send" priority is the highest of an enumerated type, with "SystemIdle" being the lowest. When I invoke the button's command with that priority, the Cancel goes through immediately.