在WPF中更新其中的元素时冻结列表框 [英] Freeze listbox while updating elements inside it in WPF

查看:62
本文介绍了在WPF中更新其中的元素时冻结列表框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,



我正在建立一个真正的iskple聊天客户端,它基于MySQL数据库和PHP脚本。要下载消息,我调用一个PHP脚本,在页面上为我编写它们,然后我用 c得到结果c.DownloadString(mywebpage.php)其中c是一个WebClient。



客户端的结构是一个代表消息的类,名为 ChatMessage 另一个类, ObservableColleciton< ChatMessage> 继承。然后,在窗口(包含ListBox)内,我立即收集集合类并将ListBox的ItemsSource属性分配给该对象。然后,通过使用 DispatcherTimer ,每隔10秒我调用集合类刷新方法。



由于这必须处理网络,我决定使用另一个线程来调用刷新方法(我在 Window 中创建线程,并使用

Hi everybody,

I'm building a really iskple chat client which is based on a MySQL db and a PHP script. To download the messages, I call a PHP script which writes them for me on a page and then I get the results with c.DownloadString("mywebpage.php") where c is a WebClient.

The client is structured with a class which represents a single message called ChatMessage and another class, which inherits from ObservableColleciton<ChatMessage>. Then, inside a window (which contains a ListBox), I instantate the collection class and assign the ListBox's ItemsSource property to that object. Then, by using a DispatcherTimer, every 10 seconds I call the Refresh method of the collection class.

As this has to deal with web, I decided to use another thread to call the Refresh method (I create the thread inside the Window) and to add items to the colleciton by using

App.Current.Dispatcher.Invoke(new Action(() => { this.Add(new ChatMessage(From, Body, Date)); }));





在方法结束时,我触发一个名为 RefreshedList的事件



At the end of the method, I fire an event called RefreshedList

App.Current.Dispatcher.Invoke(new Action(() => { RefreshedList(); }));





并且在窗口内有一个方法,如果满足某些条件,方法滚动 ListBox 到最后一项。



and there is a method, inside the Window which is called and if some conditions are met, the method Scrolls the ListBox to the last item.

if (!(this.IsActive == true && this.lstChat.IsFocused == true))
            {
                this.lstChat.ScrollIntoView(ch.Last());
            }





问题是在刷新方法的开头我删除所有集合中的项目添加其他项目:





The problem is that at the beginning of the Refresh method I delete all the items in the collection to add the other ones:

c.UseDefaultCredentials = true;
                            c.Credentials = Settings.Auth;
                            string t = c.DownloadString(Settings.ChatRead);
                            string[] Content = t.Split('\x6');
                            App.Current.Dispatcher.Invoke(new Action(() => { this.Clear(); }));
                            foreach (string s in Content)
                            {
                                try
                                {
                                    if (String.IsNullOrWhiteSpace(s))
                                        continue;
                                    Regex Finder = new Regex(@"\[[^\]]*]");
                                    var Matches = Finder.Matches(s);
                                    string From = Matches[0].Value.Substring(1, Matches[0].Value.Length - 2);
                                    string Date = Matches[1].Value.Substring(1, Matches[1].Value.Length - 2);
                                    string Body = s.Substring(Matches[1].Index + Date.Length + 2);
                                    App.Current.Dispatcher.Invoke(new Action(() => { this.Add(new ChatMessage(From, Body, Date)); }));
                                }
                                catch (Exception)
                                {
                                }
                            }
                            if (RefreshedList != null)
                            {
                                App.Current.Dispatcher.Invoke(new Action(() => { RefreshedList(); }));
                            }





当我清除列表时,ListBox会变空几毫秒,但这是可见的,当我向下滚动时,列表框闪烁,因为这个清晰,添加和滚动实际上是可见的。



我只需要冻结Listbox的刷新直到我添加了所有内容ObservableCollection的项目...



我还要补充说,如果方法被同步,则此问题不存在或它是不可见的......(显而易见,同步方法在没有Dispatcher的情况下执行)



你能帮我解决这个问题吗?



非常感谢!!



Lusvardi Gianmarco



and when I clear the list, the ListBox becomes empty for a few milliseconds, but this is visible and, when I scroll down, the listbox "blinks" because this clear, adding and scrolling is actually visible.

I just need to freeze Listbox's refresh just until I have added all the items to the ObservableCollection...

I have also to add that if the method is called synchronously, this problem does not exist or it is not visible... (Obiviously, the synchronous method is executed without the Dispatcher)

Could you please help me with that problem?

Thanks a lot!!

Lusvardi Gianmarco

推荐答案

请参阅我对Philippe Mori对问题的评论的评论。

您可以使用基于的数据源System.Collections.ObjectModel.ObservableCollection<& gt;

http://msdn.microsoft.com/en-us/library/ms668604%28v=vs.110%29.aspx [ ^ ]。



这个想法是:你修改的不是UI,而是修改数据,处理事件 CollectionChanged PropertyChanged 负责UI更新。这种技术非常有用,因为这是UI中的推送技术 http://en.wikipedia。 org / wiki / Push_technology [ ^ ]。



你可以找到许多解释这种方法的手册:

http://msdn.microsoft.com/en-us/library/ms748365%28v=vs.110%29.aspx [< a href =http://msdn.microsoft.com/en-us/library/ms748365%28v=vs.110%29.aspxtarget =_ blanktitle =New Window> ^ ] ,

http://www.c-sharpcorner.com/UploadFile / e06010 / observablecollection-in-wpf [ ^ ],

使用ObservableCollection< T> [ ^ ],

http://stackoverflow.com/questions/21128666/how-to-bind-observablecollection-with-listbox-in-wpf [ ^ ](专门针对 ListBox )。



-SA
Please see my comment to the comment to the question by Philippe Mori.
You can use the data source based on System.Collections.ObjectModel.ObservableCollection<>:
http://msdn.microsoft.com/en-us/library/ms668604%28v=vs.110%29.aspx[^].

The idea is: you modify not UI but data, and handling of the events CollectionChanged and PropertyChanged takes care of UI update. This technique is very beneficial, because this is the push technology in UI: http://en.wikipedia.org/wiki/Push_technology[^].

You can find a number of manuals explaining this approach:
http://msdn.microsoft.com/en-us/library/ms748365%28v=vs.110%29.aspx[^],
http://www.c-sharpcorner.com/UploadFile/e06010/observablecollection-in-wpf[^],
Working with ObservableCollection<T>[^],
http://stackoverflow.com/questions/21128666/how-to-bind-observablecollection-with-listbox-in-wpf[^] (specifically for ListBox).

—SA


这篇关于在WPF中更新其中的元素时冻结列表框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆