Click here to Skip to main content
15,885,985 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I am a beginner with C# and WPF.
I would like to read from a CSV . I would like to pick up a line from the CSV each 30 second and with the fields of the line update the values in a User control ( a gauge with a Text box).
What I have already: I am doing something similar with a button event. I am reading the CSV with StreamReader and ReadLine and I am storing the data in a List<string>. I use for the user control INotifypropertyChanged and I am binding the control properties to a data context ( values from the list). Then, when I press the button , the values are taken from to the next csv line (next list position) and consequently are updated into the user control.


I want to do it automatically , I want to read the next line each 30 seconds.I read about timer and I did some tests printing the objtects of the list each 5 secodnds ,but it is not working for my plan. Any recommendation for my objective? I don't have to much experience with events and periods.

My code in this case it is not relevant because I am asking about how to fire , read , pick up a line or execute the data update each 30 second but just in case I added the main code blocks:

User control:

XML
<pre lang="c#">    <Viewbox Grid.Column="1"  >
      <gauge:CircularGaugeControl x:Name="gaugeWindAngle"  Grid.Column="1" Grid.Row="0" Margin="5"
                                      Radius="105"
                                      ScaleRadius="60"
                                      ScaleStartAngle="140"
CurrentValue="{Binding Type}"
                                      RangeIndicatorThickness="9"
                                      RangeIndicatorRadius="45"
                                      RangeIndicatorLightRadius="8"                                                                        
                                      PointerThickness ="5"
                                      DialTextOffset="40"
                                      DialText="Wind Angle"
                                      DialTextColor="SlateGray"

                                        />
    </Viewbox >
     <WrapPanel Margin="5">
        <Label Foreground="#DFA297">Speed: </Label>        
          <TextBox
              x:Name="textboxWindSpeed" Text="{Binding TalkerID , UpdateSourceTrigger=PropertyChanged}"/>
      </WrapPanel>
    <Button Grid.Column="0"  Content="Send sentence" x:Name="b1"        HorizontalAlignment="Left"      Margin="10,10,0,0"      VerticalAlignment="Top" Click="Button_Click"     />
  </Grid>

CODE BEHIND

C#
public partial class Wind_gauge : UserControl, INotifyPropertyChanged
    {
    Trucker trucker = new Trucker();//DECLARE DATA CONTEXT AND LINK IT TO THE WIDGET properties (VALUES)
        double windAngle;
        int click = 0;
        public double WindAnglevalue
        {

            get { return windAngle; }
            set
            {
                windAngle = value;
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("WindAnglevalue"));
                }
            }

        }

        double windSpeed;
        public double WindSpeedvalue
        {

            get { return windSpeed; }
            set
            {
                windSpeed = value;
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("WindSpeedvalue"));
                }            }
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        public Wind_gauge()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(Window1_Loaded);//launched event
                
        }

        void Window1_Loaded(object sender, RoutedEventArgs e)
        {
            this.gaugeWindAngle.DataContext = trucker.sentenceReceived; // Initialize widjet value to data context
            this.textboxWindSpeed.DataContext = trucker.sentenceReceived;
            }

   private void Button_Click(object sender, RoutedEventArgs e)
        {
            sendsentence(sender, e);
                      click++;//List index         
           
        }


READING MY CSV IN class Truker to List<string>sentencesListt;:

class Trucker
   {  static Timer _timer;//test
       public  List<string> s = new List<string>(); //Repository of NMEA messages recived
       public  List<string> sentencesList
       {
            get {

               if (s == null) {
                   loadNMEAsentences();

               }
               return s;
           }        }

public Trucker()
       {
           loadNMEAsentences();// Load  messages from CSV
        /*   foreach (string l in sentencesList)
           {
               Console.Write("Sentences:" + l);
           }
           Console.Read();*/
              }

   public void loadNMEAsentences()
       {
           _timer = new Timer(3000);
           _timer.Enabled = true;
           _timer.Elapsed += new ElapsedEventHandler(timerRead);
       }//end method


   void timerRead(object sender, ElapsedEventArgs e)
       { s= new List<string>();
           System.IO.StreamReader file =
            new System.IO.StreamReader(@"C:\Users\........\Data\NMEAmsg_wind.csv");
           string line;
           while ((line = file.ReadLine()) != null)
           {                   if (line.IndexOf("$IIMWV", StringComparison.CurrentCultureIgnoreCase) >= 0)
               {
                   s.Add(line);// Insert sententece to the repository sentences list
                   // Console.WriteLine(line);
               }
           }
           file.Close();        }
Posted
Updated 30-Sep-14 23:37pm
v4
Comments
Sinisa Hajnal 1-Oct-14 3:44am    
Why couldn't you do it with Timer? What was the problem?
Kinna-10626331 1-Oct-14 4:28am    
I am not sure , I just improve my qustion adding that part. Probabily I am doing some mistake with the event associated to the timer.

1 solution

I solve it , I apply the timer into the user control and elapse the interval with a read event:

C#
public Wind_gauge()
      {
          InitializeComponent();
          this.Loaded += new RoutedEventHandler(Window1_Loaded);//launched event
          timer = new Timer(3000);
          timer.Enabled = true;
          timer.Elapsed += new ElapsedEventHandler(timerRead);

      }

      void Window1_Loaded(object sender, RoutedEventArgs e)
      {
          // this.gauge_rpm.DataContext = TRC.Fields.RPMDemandValue.ToString(); //Remaind it
          this.gaugeWindAngle.DataContext = trucker.sentenceReceived; // Initialize widjet value to data context
          this.textboxWindSpeed.DataContext = trucker.sentenceReceived; // Initialize widjet value to data context


          }


      void timerRead(object sender, ElapsedEventArgs e)
      {
         //pick up a sentence here . It would be executed each 3 seconds
       if (click < trucker.sentencesList.Count)
          {
              string[] fields = trucker.sentencesList[click].ToString().Split(',');
              trucker.sentenceReceived.Type = fields[1].ToString();
              trucker.sentenceReceived.TalkerID = fields[1].ToString();
}
              click++;//Index list
}


The reading Csv step and store the data into the list is as I did in the code of the cuestion without timer.
 
Share this answer
 
Comments
Phil J Pearson 1-Oct-14 8:23am    
I'm glad you fixed it, but I think there's a much better way than using a timer. What if there isn't a new line in the csv file after 3 seconds? Or what if there's more than one new line after 3 seconds?
Look at the FileSystemWatcher class. You can set up a simple watcher to raise an event when the file changes -- much better than using a timer.
Kinna-10626331 1-Oct-14 10:31am    
Thank you Phil , when I was looking for a solution I found about fileWatcher but at that moment I though it was valid only for check what change in a directory/folder ( all the examples checked that) and quickly I started to program with timer. I will change it.

On the other hand , as a detail: in an else I included click=0 and then starts to display again the values until infinite. It was only for test of course xD

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