wpf - How to thread a viewlist custom view binding so that the UI doesn't freeze -



wpf - How to thread a viewlist custom view binding so that the UI doesn't freeze -

i new wpf, though have tried read much can, newbie in need of wisdom wpf sages here.

i have viewlist custom view display tileview of linecharts. user selects item in separate listbox, sets datasource used in listview. problem ui freezes while listivew generating view. here how layout looks:

((sorry, new @ site can not post images, yet, here link: screenshot))

the datasource consist of class contains descriptive properties , list of list of datapoints (x,y). tileview takes list of list of datapoints , generates 1 line chart each listitem using list of datapoints draw line.

currently have datasource list holding 200 items , each item has 200 datapoints (x,y).

when select item in listbox of left, utilize selectionchanged event set itemssource property listview new dataset. problem ui freezes until charts generated.

i have been trying different approaches without success. tried set datasource asynchronous one:

dataseries="{binding isasync=true, path=data}"

this helps tinny tinny bit releasing ui before view rendered. means after changing datasource freeze ui moment, release showing view 200 empty charts , after bit refreshing view populated charts.

i tried set binding within thread this:

private void list_selectionchanged(object sender, selectionchangedeventargs e) { //find selected itemsource string runname = (string)experimentlist.selecteditem; experimentalrun selectedrun = _experimentruns.find(item => item.name == runname); //bind datasource thru new thread thread newthread = new thread(lstproductsnewsource); newthread.start(selectedrun); } private void lstproductsnewsource(object selectedrun) { this.dispatcher.begininvoke(dispatcherpriority.background, (threadstart)delegate() { lstproducts.itemssource = ((experimentalrun)selectedrun).rungraphdata; }); }

lstproducts name of listview has tileview of charts. rungraphdata porperty points @ list of list of datapoints.

i hoping release ui did not work. in case there no time consuming process before databind, info readily available in memory, time consuming creation of viewitems , databinding of them, not rendering.

as additional details specify charts generated usercontrol , here how xml of tile view looks:

<local:tileview x:key="imageview"> <local:tileview.itemtemplate> <datatemplate> <stackpanel width="150" verticalalignment="top"> <local:graph dataseries="{binding isasync=true, path=data}"/> <textblock textwrapping="wrap" horizontalalignment="center" text="{binding >isasync=true, path=containername}" ></textblock> </stackpanel> </datatemplate> </local:tileview.itemtemplate> </local:tileview>

the graph usercontrol typical chart command receives dataset , binds it.

i seek advice on how manage maintain ui responsive while listview binding. can help me?

edit:

i forgot mention tried utilize virtualization on listview without noticeable difference:

<listview name="lstproducts" view="{staticresource gridview}" >virtualizingstackpanel.isvirtualizing="true" > </listview>

i expecting load current window worth of items , when scroll downwards start loading new items, when utilize isvirtualizing property set true seems load @ once, same delay , if scroll downwards there no delay giving me impression items present.

edit 2: found question in site reply provided type of solution: link

following advice provided in after mentioned thread, modified previous threading effort trying encapsulate entire databinding event single background thread pumping info 1 graph @ time, taking advantage of observablecollection auto-updating properties. create empty datasource , assign it, add together elements datasource 1 1 creating thread background priority every time add together point. looks this:

private void experimentlist_selectionchanged(object sender, selectionchangedeventargs e) { //find selected itemsource string runname = (string)experimentlist.selecteditem; experimentalrun selectedrun = _experimentruns.find(item => item.name == runname); //create , empty datasource filled 1 item @ time experimentalrun pumprun = new experimentalrun(((experimentalrun)selectedrun).name); lstproducts.itemssource = pumprun.rungraphdata; //fill emtpy source using new thread per item added foreach (var item in selectedrun.rungraphdata) { pumpexperimentalrundata pump = new pumpexperimentalrundata(pumprun, item); thread newthread = new thread(pumpadd); newthread.start(pump); } } private void pumpadd(object pumpexperimentalrundata) { this.dispatcher.begininvoke(dispatcherpriority.background, (threadstart)delegate() { ((pumpexperimentalrundata)pumpexperimentalrundata).pumprun.rungraphdata.add(((pumpexperimentalrundata)pumpexperimentalrundata).item); }); }

this approach seems work, worried creates many threads (200) every time alter datasource ... have read far recommends utilize few threads, , doesn't qualify few think. differently, out of ideas.

can see error of ways or point out improve approach?

you have utilize virtualizingstackpanel.

<listview.itemspanel> <itemspaneltemplate> <virtualizingstackpanel/> </itemspaneltemplate> </listview.itemspanel>

wpf multithreading data-binding listview asynchronous

Comments

Popular posts from this blog

iphone - Dismissing a UIAlertView -

intellij idea - Update external libraries with intelij and java -

javascript - send data from a new window to previous window in php -