Binding WPF textBox Large Text async with possibility of cancellation - c#

I have listbox and for each selected item I need bind data (Large Text) to separate TextBox placed on form.
It works fine with small text less than 16 kb.
but with large text I have UI Freeze because of TexBox Rendering is taking long time.
IDEA is to have Async Binding (even Manually on selected even Line by Line), with ability to have cancelation of binding. Cancellation should occur if new item will selected during a rendering.
P.S. Same code in WinForm works much faster.
Could you help me on that, or give another idea ?
Thank you in Advance.

Read about UI virtualization here: https://learn.microsoft.com/en-us/dotnet/framework/wpf/advanced/optimizing-performance-controls

I found way to achieve result.
1) Using FlowDocumentReader instead of TextBox
2) Load document large text with async, and cancels previous load, if new document load occurs.
Just want to share with a solution to the others. 

Related

UI is not responsive when datagridview loading data in c#

I have a listbox, datagridview and textbox in winforms.
Here is what I am trying to do
When the user selects an item in listbox, datagridview is loaded with some data regarding to the item selected and also there is a autocomplete textbox with a custom source which changes dynamically based on the item selected.
datasource for datagridview and autocomplete textbox is from the rdbms (MYSQL).
private void listBox1_SelectedValueChanged(object sender, EventArgs e)
{
string item=listBox1.SelectedValue.Tostring();
UpdateDataGridView(item);
UpdateACTextBox(item);
}
Until this operation is completed, user cannot able to select another item in listbox, it takes almost 10 seconds to finish.
To resolve this, I came across some solutions like asynchronous method.
Which is the best way to resolve this problem?
Backgroundworker,
async and await,
threadpool,
multithreading.
Please suggest something if I have not researched properly.
What is the conventional way developers follow to these types of problems?
UPDATE:
I forgot to mention that I am using VS2010. Since async and await is not supported in vs2010. I think I need to drop that option.
Thanks in advance
It seems to me that the problem is that the amount of data you are loading to the listView is to big. So i would suggest using a background task in combination with the VirtualMode of the listView. In virtual mode the datas are not stored inside of the listView you have to store the values outside in a list of your own. If needed the listView will call a event to ask you for the value. Simply return a dummy or use old values if the data is not available. This will let the listview simply blanke or showing the old values. After the values are finished copied in a list simply exchange the pointer (variable) of the list with a atomic operation. From that point on the new datas are used to update the list and not the old one. Call update function to load the new valuses. This methode allowes it although to update the data in the background and update it from time to time. Only drawback you need to store the values of your list twice. Inside of the old shown buffer and inside of the new currently updated one. I hope that helps.

binding a datagridview in background(or using a thread) in c#

I have a list (of type class). It has several rows..44000 for example, and I need to bind it to a datagridview in c#. I wanna do it without taking the control of the UI from the user. Even when I am using a background worker, the title bar says not responding.
its as simple as
dataGridView1.DataSource = bars; where bars is a bindinglist which has 44000 rows.
This single line is clogging up all the UI and the time..
Any ideas?
My suggestion is on binding smaller batches with the ones in view or will be near in view only. And dynamically as the user scroll, update this binding list.
There isn't a perfect solution as the size of your list is so long, binding the whole thing one way or the other will yield performance hit.

WPF (irc) chat log control

I'm trying to learn WPF and was thinking about creating a simple IRC client. The most complicated part is to create the chat log. I want it to look more or less like the one in mIRC:
or irssi:
The important parts are that the text should be selectable, lines should wrap and it should be able to handle quite large logs.
The alternatives that I can come up with are:
StackPanel inside a ScrollViewer where each line is a row
ListView, since that seems more suitable for dynamic content/data binding.
Create an own control that does the rendering on its own.
Is there any WPF guru out there that has some ideas on which direction to take and where to start?
I suggest you start with a good object model independent of the UI, and then try a multi-line TextBox or a RichTextBox.
Whether these will suffice will depend on exactly how long you want the log to be able to get. If you run into performance issues, you may need to look at virtualization.
First of all, you should consider if you want to select only entire row (like in a listbox), or if you want to select certain characters from a row (like in a textbox).
In the first case, I think a ListView or even a ListBox should be enough, both of them support virtualization when bound to collection and there should be no problem with huge amounts of data. A stack panel inside a ScrollViewer is a little bit like reinventing the wheel for this case and creating a new control is not a very inspired approach in my opinion (as the functionality you want can be achieved with the existing controls, in WPF).
In the second case, if you want to select some text inside of a line, or if you want word wrapping for your longest lines in the log and want to select individual parts of the wrapped lines, then you need to use a control more oriented on displaying text. Kent already suggested a RichTextBox, I would add AvalonEdit control or even the WebBrowser control in which you directly modify its HTMLDocument.
I would suggest to use RichTextBox too, and store items in a log file or database, if you run into performance issues.
Another solution is to use the WPF WebBrowser control and modifiy its HTML content with:
webBrowser.NavigateToString("<HTML><H2><B>This page comes using String</B><P></P></H2></HTML>");
More information about using WebBrowser control

a loading screen for a c# wpf listbox

I'm using a list box where there are on average about 500 thumbnails (items) that can be sorted and searched.
Since I'm using default databinding and search descriptors (which I've heard are slow due to reflection) the list takes a noticeable pause of a few seconds loading, sorting, and searching (the list dynamically updates based on the contents of the search box so the first one or two letters typed are really slow).
I don't think I can fully do away with reflection give the timeframe for the project, and speed isn't super essential, but I'd like some kind of graphical indication of the delay so it doesn't confuse the user. How could I do something like a website video loading screen where the listbox grays out and some kind of loading circle indicates it's processing until the list is ready? Or even just grayed out with the words "Loading..." for a few seconds could work. Any ideas?
Thanks in advance for your help and suggestions!!!
Silverlight-Controlkit comes with a very handy "busyindicator"-control... too bad there seems to be no such thing for WPF by default.
But I found this seemfully comparable control for you:
http://sweux.com/blogs/pombeiro/index.php/2009/12/01/a-busy-state-indicator-attached-behavior/
download-source:
http://gallery.expression.microsoft.com/en-us/BusyIndicator
Like Veer wrote, BackgroundWorker is probably your best bet.
For the graphical indication of progress and/or delay, take a look at
http://www.codeproject.com/KB/WPF/WPF_Loading_Wait_Adorner.aspx
It looks like pretty much exactly what you want to do.
Try BackgroundWorker
Use the DoWork method to update your list dynamically based on the search keyword
Use the ProgressChanged method to update your UI with some animation saying 'Loading'. A ProgressBar could be used
Use Dispatcher to access your list inside the DoWork method

Keep UI Thread free

I have a form with two panels(top, bottom), each panel contains grids. Basically, it's a Master-Detail form where selecting a row from the top grid would show details in the bottom grid.
Binding the data to the detail grid is taking some time. Since binding is done on UI thread, it blocks the thread and therefore the user cannot select another row from the master grid until the binding is done.
Please note that by binding I don't mean getting data from data source. It's the actual binding that's taking longer as it does a lot of data massaging. How can I keep the UI thread free while the detail grid is doing it's binding?
Thanks a million.
You can't. The update of the UI has to be performed on the UI thread.
You may be able to speed up the binding by using things such as BeginUpdate/EndUpdate which is available on some controls but as you don't specify what you are using I can't say if that's available.
You can use a background thread to perform your data retrieval, then use the UI thread to display it.
If I were you, it sounds like you are dealing with a LOT of data, and I would separate all the "massaging" you can into a separate thread process.
So maybe for example when a master record is created, you "manually" spin off the detail data in a background thread to another dataset and do the massaging, then just bind the resulting dataset to the grid. That way the only thing taking place on the UI thread is just the UI binding.
Ultimately if it's taking that long, you may be approaching a critical point in your application where you need to manually do what you need to do in code rather than using the out of the box data binding features in .NET.
Finally I found the solution. The solution doesn't include multithreading to start with. As I said that the delay was in binding the grid meaning the main thread was held, we couldn't do much. So the solution is to bring delays. When user selects the master row, a timer ticks off for a certain time. If another request is made before the time is expired, timer gets restarted. This is we ignore all calls that are made because user was clicking or selecting rows too fast. Once timer is expired, I take the selected row and display data. Simple and elegant solution.

Categories