Click here to Skip to main content
15,507,380 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
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
C#
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)
C#
public MainWindow()
        {
            InitializeComponent();
            EmailParser parser = new EmailParser(true, "test@mail.cz", "password");
    //Could be problem with Name of the class? I had to rename it, but how I see, it didn't change it properly. But the window is showing...
        }


Constructor in EmailParser class

C#
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
C#
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.AuthenticationMechanisms.Remove("XOAUTH");

                    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

C#
<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

C#
<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
Posted
Comments
Gerry Schmitz 27-Jul-22 12:31pm    
You've shown "one statement" that relates to your heading: ItemSource = xxx.

Everything else, is useless from a problem solving point of view.
Member 15627495 31-Jul-22 5:11am    
as every componant, your datagrid needs :
- init()
- clear()
- populate()

3 functions, to make live your componant.
It's a base for the content of your datagrid

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900