Any way to programmatically build UI elements off the UI thread? - c#

I know I need to create and add elements to another element on the main UI thread in WPF and you can easily do this when on another thread using the Dispatcher.
However I would like to build my elements off the UI thread then add them all in one batch if possible.
This is because I am building thousands of elements and the couple seconds it takes on the UI thread freezes the whole application.
Is there any way to do this?

I don't think so; however, you can create a smoother user experience by gradually loading the elements without making the GUI hang completely. This can be done by subscribing to the CompositionTarget.Rendering event, which will be called each time a frame is rendered. If you maintain a list of the view models (and corresponding control types) that you need to add, you can create some (say, fifty) of them and add them the visual tree inside the event handler. The next time the event is invoked, you add fifty more, and so on.

It could be possible, what you do is you create two UI threads. On one UI thread you build up your window and show some kind of progress indication (progress bar) on the other UI thread. Make your window visible when you've built it up.
http://eprystupa.wordpress.com/2008/07/28/running-wpf-application-with-multiple-ui-threads/

I recommend to you to use some composite application patter, like Prims. See Patterns For Building Composite Applications With WPF.
Prism allows to decouple your apps components, and also load them on demands.
Also you can see: Prism
Hope this helps...

Related

In a WPF project, how do I initialize my Window and controls and then jump into a main loop?

Apologies if the question is poorly phrased, new to C#. I'm trying to make a text adventure. I've already written all the underlying logic, and decided to try and use a WPF for basic graphics. So I initialize the window with all the controls I need and then loop through my main loop until you trigger an exit. I initially tried putting the loop right after initializing the window.
public MainWindow()
{
InitializeComponent();
Game.Logic();
}
This didn't really work well as the Window stopped initializing at all.
So I googled around a bit and tried using a Loaded Event. Once I did that, the Window pops up when I run the code, but none of the controls appear and the window is frozen. The same problem persisted when I tried to use a Loaded Event for the controls themselves. While there may be some kind of bug in my Game Loop, I think the Window should at least be able to initialize all its controls if I'm jumping into the Loop correctly. Would the right thing to do be to go into the App file and use a Loaded Event there? Or am I just completely out of line somehow?
You're pretty far out of line.
By executing a tight loop on the UI thread, you are killing any chance of the UI ever updating, even if you got past your current roadblocks. As far as Windows is concerned; you are "frozen".
You need to run your logic loop on another thread and use Dispatcher.BeginInvoke to get any UI updates (and only UI updates) back onto the UI thread. While typically not as useful in game contexts, also consider using the MVVM pattern with Bindings as its harder to fall into this trap.
For a text adventure, I would strongly recommend the MVVM pattern as all of your elements are easily represented as bound items/collections. Plus, it gets you into good modern development practices :)
I would recommend using Background Worker, which will allow you to carry out UI updates using multi-threading to ensure your main thread remains responsive.

Hosting Controls over Multiple Threads in .Net

I have a problem and after three days I still can not find a answer.
I am creating a usercontrol. This control has two controls hosted on it. One is an edit field and the other is a margin that will hold line numbers and other user added stuff.
What I am trying to do is instantiate these to separate controls in their own threads and perform all tasks on these threads eg painting and updating. The usercontrol thread will simply filter messages and direct same to the correct control. I will be doing this by overriding the WndProc method.
Doing all the message stuff I am fine with however how do I instantiate the controls. Once the thread that creates these controls finishes wont the threads die and the controls became inaccessible. Sorry no code at the moment, I tend to do a lot of research before any coding but I can't seem to find anything that can be of help.
This is not going to work very well. All UI elements (forms, controls, etc.) have thread affinity requirements that dictate that they can only ever be accessed from the thread that created them. Trying to embed a control hosted on one thread in another control from another thread is an effort in futility. Even if you can get it work (and use the term "work" loosely here) the results may be unpredictable at best. You need to rethink your approach. It would be much better to host all of the controls on the same thread and then shuttle off any time consuming operations to a worker thread. Remember, keep the worker thread busy with non-UI related operations only. Once the operation is complete then you can marshal over the results to the UI thread where it can dispatched appropriately to the controls.

Copy an entire DevExpress.XtraTreeList.TreeList in C#

The scenario:
I am creating and populating a Treelist using a database.
This is a rather time-consuming task, and don't want to hang the gui (nor have any "progress-bar" etc).
So I decided to move all this to a Backgroundworker, but since I cant update the tree from another thread then the one who created it I am creating a temp-tree in the background-thread and when done, just copy the entire contents to the GUI-shown tree.
What is the best way to traverse and copy all nodes, node-data etc?
Is there another (better?) way to do this, ie build/create a tree in a Backgroundworker and showing it in the GUI?
Edit: I am aware of the 'hack' of populating a GUI component in a background-thread, but since I just got thrown into this project and asked to "stop the gui from hanging quite often" with a very limited time frame, re-writing the loading and creation of the data is not really an option (even though this would ofc be the best practice).
I just changed the "CreateTree"-function to run in a new thread, pass the newly created tree to "ThreadComplete" and copy it.
Cheers
UI elements, like a TreeView, should stay in the UI end of things. There are technical reasons for this - Windows doesn't allow updating UI elements from any threads but the main UI threads - but also architectural reasons: your back-end DB-accessing code shouldn't be tightly coupled to any specific UI implementation. If you decide to switch from TreeList to a different control, by DevExpress or any other vendor, you'll have to replace code all through your system.
What you want to do is have your back-end code create a more general data structure, like a list of business objects with a hierarchical structure, like this:
public class MyBusinessObject
{
public string Name {get;set;}
public List<MyBusinessObject> ChildObjects {get;}
}
and return a list of MyBusinessObject from your background thread. This list should be connected to your TreeList using databinding. You didn't specify what UI platform you're using - XtraaTreeList is a WinForms control, right? - but all common frameworks have databinding options to bind this list of business objects to the UI control, rather than have you do all the work yourself.
In order to update a Component from another thread, you can use a SynchronizationContext and then traverse it like it's in the same thread.

Methods to update GUI in WPF

I would like to ask what method to update GUI is better for my scenario.
I would like to manipulate (move) multiple controls from point to point based on the input from user's touches.
I know a few difference way to do it.
Dispatcher Timer & Timer. (What's the difference between them?)
BackgroundWorker.
Storyboard & BeginAnimation Method.
Which of these method is generally recommended to use in term of memory and resource saving and simpler to code?
Thank you!
I suppose these 3 SO QA should help u understand all the differences:
DispatcherTimer vs a regular Timer in WPF app for a task scheduler
Comparing Timer with DispatcherTimer
WPF BackgroundWorker vs. Dispatcher
Apart from the link given by Vijay, a common concept that is vital in WPF application while you manipulate visuals is Dispatcher
In short, a Dispatcher is a message queue gateway manager to the UI, that receives delegates and prioritises them to execute on the given thread. In WPF, UI thread is STA. Also any visual created on UI thread has a thread affinity which means if you are performing any multi threaded functionality (for faster performance) then when it comes to manipulating those visuals such as updating their values, increasing / deacresing their size, focusing them, transforming them etc. has to be done using the UI Dispatcher.
Now back to your situation, when you want to move items, translate transform animation is a good option.
Hope this helps you in correct direction.

WPF Multithreaded UI - Usercontrols

I have seen some code samples of multi-threaded UIs in WPF using multiple windows where each window runs on it's own UI thread. I'm curious though - is there a way to accomplish this with embedded controls?
For example lets say I have usercontrol1 and usercontrol2 both embedded in Window1. Usercontrol1 starts to spin and blocks the main UI thread. The window and usercontrol2 are effected. Is there a way to make it so even if usercontrol1 blocks, Window1 + usercontrol2 are still responsive?
Let us assume we don't control the developers of usercontrol1 - so we can't tell them to make their control behave.
Let us also assume the exchange of data between usercontrol1 + 2 is a must.
Should I be exploring something like AddIn's?
You can't "run" the controls on another thread (as with Winforms, the controls themselves must be created and run on the same thread as the top-level parent), but there's nothing stopping you from initiating actions on another thread from a user control. You just have to ensure that you use the Dispatcher to Invoke any operations that will have a direct effect upon the control itself. Behind-the-scenes processing can be done entirely on another thread, though; it's just the physical updating of the UI that has to be invoked back via the Dispatcher.
EDIT: After the question was edited, no, there is no way to move all of the "work" that a particular component performs to another thread. If you can't control the development of the component in question, then you're at the mercy of the developer and where he decides to execute the code.
As on the top you have visual (Window) which is inheriting from DispatcherObject. It is designed as STA threading model, in which single thread is accessing the object methods and properties.
That is why both controls must be created in the same thread as Window.
If you need to exchange data between controls and you are not controlling developers of those controls I would consider using PRISM or other MVVM framework. In prism you have EventAggregator which is basically subscriber publisher pattern your UserControl1 can publish something and the other one if it's subscribed will receive that.

Categories