-1

I am developing an application related to display screen at Airports. For that purpose, I intend listbox UI controller to the display that includes Flight information, like (Flight#, Destination, Status). I wish to include the functionality so that an automatic change of status takes place after some specified time. For example, after 10 minutes, Check-In gets changed to Boarding and after 10 more minutes, boarding gets changed to Ready-To-Takeoff.

I am reading the data from file and adding strings into listbox as individual flight details as: PK101 London Check-In. On button click event, file is read and flight data is added to listbox as string rows. However, I am unable to implement, status can change its value.

void addFlights()
    {


      string[] 
  lines=File.ReadAllLines(@"D:\FlightsSchedule\flights.txt");
        foreach (string line in lines)
        {
            listBox1.Items.Add(line);

            Thread.Sleep(500);
        }

    }
    private void button1_Click(object sender, EventArgs e)
    {
        Thread thrd=new Thread(addFlights);
        thrd.Start();

    }

On the basis of certain time (System generated), status on listbox may get changed as: Flight Destination Status

After chek-in: PK102 KHI boarding
After Boarding:TK103 London Take-Off

Analyzer
  • 79
  • 7
  • 1
    Can you clarify your question a bit? I am not sure if you are asking for how to get the `Listbox.Items` to refresh or how to get run a timer. – Kami Sep 09 '19 at 11:20
  • 1. It is kind of updating the rows of listbox on the basis of time. – Analyzer Sep 09 '19 at 11:31
  • I intend to make each row as separate thread than this functionality is quite possible. How can set each row of listbox as a seperate threas? – Analyzer Sep 09 '19 at 11:33
  • 1
    Why do you want to have each item as a separate thread? – Kami Sep 09 '19 at 11:39
  • 1
    Your question fails to include a clear problem statement, and also fails to include a [mcve], never mind a good one that would adequately illustrate your problem. From the little bit of code you've posted, it's apparent that you would run into the cross-thread exception that occurs when you try to access UI objects from other than the UI thread, hence the duplicate @SteveB's selected for your question. If that does not address your question, please post a new question, this time taking care to provide all relevant details, including a precise, clear _question_. See also [ask]. – Peter Duniho Sep 09 '19 at 16:11

1 Answers1

1

As the number of the line youre reading is equal to the index it has when displayed in the list box, I suggest you to cache the hashes of each line a int[] containing the files lines. And when the update function is called you read and hash the text document again (into a new string[]) creating a 2nd int[] and then compare the line hashes. If the new hash is different you note the index in a List. Then you can replace the Listbox items at the indicies yo noted in the List with the string from the new string[]. Afterwards you replace the old one with the new string[].

private string[]display;
private int[]lineHashes;

public void OnUpdate()
{
   //read file
   string[] newLines = File.ReadAllLines(filePath);

   //grow array if nessesary
   if(display.Length < newLines.Length)
   {
      Array.Resize(display, newLines.Length);
   }   
   //detect changed lines
   var replaceLines = new List<string>();
   var replaceIndicies = new List<int>();
   for(var i = 0; i < newLines.Length; i++)
   {
      var line = newLines[i];
      var lineHash = GetStringHash(line);
      if (lineHash != lineHashes[i])
      {
         replaceLines.Add(line);
         replaceIndicies.Add(i);
      }
      lineHashes[i] = lineHash;
   }
   //replace lines display and Listbox
   for(var i = 0; i < replaceIndicies.Count; i++)
   {
      var newLine = replaceLines[i];
      display[replaceIndicies[i]] = newLine;
      if(ListBoxDisplay.Items.Count + 1 > i)
         _yourWindow.ListBoxDisplay.Items[i] = newLine;
      else
         _yourWindow.ListBoxDisplay.Items.Add(newLine);
   }
   //swap display with newLines
   display=newLines;
}

private int GetStringHash(string str)
{
   //whatever hash alorithm you like, just copypaste one from stackoverflow.com
}

In regards to your comment I assume that the code runs in a seperate thread from the UI, you need to consider the following code.

In regards to how to launch a seperate thread simply start it in from your main thread using new Thread({updateThread.Start();});. Here updateThread is a local variable in your main thread to the initialized class with my code, and Start() kicks off a FileWatcher or time you would then have to implement. It should just run the OnUpdate() function.

The constructor for the class that you want to run in a new thread should look something like this:

YourWindow _yourWindow;

FlightListUpdater(Window yourWindow)
{
   _yourWindow = (YourWindow)GetWindow(yourWindow);
}

if youre on WPF you will have to use a Dispatcher to set ListBox:

YourWindow.Dispatcher.Invoke(delegate => 
{
   _yourWindow.ListBoxDisplay.Items[i] = newLine;
}

if you mean a GridView not a ListBox then you will have to use a converter method that take a string and

Prophet Lamb
  • 530
  • 3
  • 17
  • I really can't catch up your answer. How can I easily set row of listbox as separate thread in context of above code. That means while each line from file, it should initiate new thread – Analyzer Sep 09 '19 at 11:35
  • 1
    I hope I now answered your question. – Prophet Lamb Sep 09 '19 at 11:57
  • I will get back to you as soon as I implment this. – Analyzer Sep 09 '19 at 12:36
  • Little more help will be appreciated. How to update particular word in item of list o the basis of certain system generated time. For instance: check-in gets updated as boarding after 10 minutes? – Analyzer Sep 09 '19 at 12:39
  • The method "Update()"does that automatically, it finds the lines that changed and then changes the listbox line with the Code "_yourWindow.ListBoxDisplay.Items[i] = newLine;" here "_yourWindow" is a reference to the GUI and "ListBoxDisplay" is the name of the listbox you display. – Prophet Lamb Sep 10 '19 at 07:50
  • Though I would advice to wrap the call in a method in the GUI that Looks like this "EditLine(int index, string newLine)" instad of calling the listbox directly. – Prophet Lamb Sep 10 '19 at 07:52