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)); }));
At the end of the method, I fire an event called
RefreshedList
App.Current.Dispatcher.Invoke(new Action(() => { RefreshedList(); }));
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(); }));
}
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