I'm trying to dynamically add records to DataGrid (which I take from mails, running in the background). The problem is that when I use the method on the other thread to start the XAML window, it just prints some records not every one and not dynamically
I know, that I've pasted large code, but it is also larger project for me. I wanted to paste the most important parts. Feel free to ask for me or less :)
Contructor, where is problem. There is DataGrid with data
public AdminWindow() {
InitializeComponent();
foreach (Alert alert in Alert.alerts) {
alertToDataGrid.Add(alert);
}
AlertTable.ItemsSource = Alert.alerts;
}
Contructor for Login(and first window, if users exist, it will create new one - AdminWindow and this will be hiden)
public MainWindow()
{
InitializeComponent();
EmailParser parser = new EmailParser(true, "test@mail.cz", "password");
}
Constructor in EmailParser class
public EmailParser(bool isSSLuse, string username, string password) {
this.ServerName = "imap.outlook.com";
this.Port = 993;
this.IsSSLuse = isSSLuse;
this.Username = username;
this.Password = password;
Task.Run(() => MailKitLib(this));
}
Method in EmailParser class
public void MailKitLib(EmailParser emailParser) {
bool help = true;
Timer t = new Timer();
t.Interval = 500;
do
{
using (var client = new ImapClient())
{
using (var cancel = new System.Threading.CancellationTokenSource())
{
client.Connect(emailParser.ServerName, emailParser.Port, emailParser.isSSLuse,
cancel.Token);
client.Authenticate(emailParser.Username, emailParser.Password, cancel.Token);
var inbox = client.Inbox;
inbox.Open(FolderAccess.ReadOnly, cancel.Token);
Console.WriteLine("Total messages: {0}", inbox.Count);
Console.WriteLine("Recent messages: {0}", inbox.Unread);
for (int i = 0; i < inbox.Count; i++)
{
var message = inbox.GetMessage(i, cancel.Token);
Console.WriteLine("ID:" + message.MessageId);
if (message.MessageId != null)
{
Alert alert = new Alert(message.MessageId, message.Date.DateTime, message.From.ToString(), "PING" , "LOW");
Alert.alerts.Add(alert);
}
}
client.Disconnect(true, cancel.Token);
}
}
if (t.Interval == 0)
{
help = false;
}
} while (help != false);
}
What I have tried:
Shorten the code to just this
<pre>AlertTable.ItemsSource = Alert.alerts;
but it throws this exception
System.InvalidOperationException: 'The ItemsControl object is not consistent with the source of its items.
I also tried adding a new train to contructor, I got this exception
<pre>Task.Run(() => AddItems());
System.InvalidOperationException: 'The calling thread cannot access this object because it is owned by another thread.'
but another exception throws again