简体   繁体   中英

How to execute a Button_Click with c#

I've set up a Windows App that runs a code and updates a TextBlock when clicked. I'm trying to get the button to fire every 2 seconds, whether physically clicked or not. I'm getting the error:

Error   CS0123  No overload for 'Button_Click' matches delegate 'ElapsedEventHandler'   WpfApp1 C:\Users\User\Documents\Visual Studio 2019\Projects\WpfApp1\WpfApp1\MainWindow.xaml.cs  45      Active

Here is the code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Net.Http;
using System.Net;
using Newtonsoft.Json.Linq;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using System.Timers;




namespace WpfApp1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private static System.Timers.Timer aTimer;

        public MainWindow()
        {

            InitializeComponent();
            SetTimer();
        }

        private static void SetTimer()
        {
            // Create a timer with a two second interval.
            aTimer = new System.Timers.Timer(2000);
            // Hook up the Elapsed event for the timer.
            aTimer.Elapsed += Button_Click;
            aTimer.AutoReset = true;
            aTimer.Enabled = true;
        }

        public void Button_Click(object sender, RoutedEventArgs e)
        {
            using (WebClient webClient = new System.Net.WebClient())
            {
                var json = webClient.DownloadString("ADDRESS");

                List<string> WhoList = new List<string>();

                JArray parsedArray = JArray.Parse(json);


                foreach (JObject parsedObject in parsedArray.Children<JObject>())
                {
                    foreach (JProperty parsedProperty in parsedObject.Properties())
                    {
                        string propertyName = parsedProperty.Name;
                        if (propertyName.Equals("name"))
                        {
                            string propertyValue = (string)parsedProperty.Value;
                            WhoList.Add(propertyValue);
                        }
                    }
                }

                // Grab data from Old Who List.txt into List and merges the two lists together
                var logFile = File.ReadAllLines(@"C:\Users\User\Documents\Visual Studio 2019\Projects\WpfApp1\WpfApp1\bin\Debug\OldWhoList.txt");
                var OldWhoList = new List<string>(logFile);

                foreach (String s in WhoList)
                    if (OldWhoList.Contains(s))
                    { }
                    else
                    {
                        TextBlock1.Inlines.Add(s + " logged in at " + DateTime.Now + Environment.NewLine);
                    }

                foreach (String s in OldWhoList)
                    if (WhoList.Contains(s))
                    { }
                    else
                    {
                        TextBlock1.Inlines.Add(s + " logged out at " + DateTime.Now + Environment.NewLine);
                    }

                // Save current wholist to old wholist text
                TextWriter tw = new StreamWriter("OldWhoList.txt");
                foreach (String s in WhoList)
                    tw.WriteLine(s);
                tw.Close();


            }
        }
    }
}

I've tried creating a new method with the code separate from the button but I get an error that doesn't allow me to update the TextBlock.

I just want to be able to execute Button_Click from inside the timer.

You can't hook up a RoutedEventHandler directly to the Elapsed event of a System.Timers.Timer as it expects an ElapsedEventHandler . You may call your Click event handler from an ElapsedEventHandler though:

aTimer.Elapsed += (ss,ee) => Button_Click(this, new RoutedEventArgs());

You should use a DispatcherTimer here though since your event handler accesses UI elements. It has a Tick event:

aTimer.Tick += (ss, ee) => Button_Click(this, new RoutedEventArgs());

A System.Timers.Timer fires its Elapsed event on a background thread which will throw an InvalidOperationException when you try add inlines to the TextBlock in your event handler.

Instead of calling the Button_Click event handler from the Tick event handler, you should consider creating a method that performs the download and call this from both event handlers.

You should also look into the System.Net.HttpClient class and its async API.

No overload for 'Button_Click' matches delegate 'ElapsedEventHandler'

Means that signature for ElapsedEventHandler is void (Object sender, ElapsedEventArgs e) . I see RoutedEventArgs insteadof ElapsedEventArgs . Maybe the method address is wrong placed. Button.Click signature is different to Timer.Elapsed

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM