【问题标题】:My button needs two clicks instead of one我的按钮需要点击两次而不是一次
【发布时间】:2012-02-08 17:39:51
【问题描述】:

我正在开发一个 C# 中的小应用程序,它会刷新网页,直到满足某些条件。我有一个“开火”=开始刷新按钮和一个“停止!”应该停止操作的按钮。我的问题是点击停止按钮需要 2 次尝试而不是 1 次。下面是我的代码:

更新了带有计时器的代码。我仍然认为可以更好地使用计时器,我认为它不会在前 2-3 次刷新后每秒更新一次,或者根本不刷新。我的代码中是否有任何我无法检测到的缺陷?

private void FireButtonClick(object sender, EventArgs e)
{

    try
    {
        if (webBrowser1.Url.ToString().StartsWith("some url"))
        {
            _stopped = false;
            _timer.Tick += new EventHandler(RefreshBrowser);
            _timer.Interval = (1000) * (1);
            _timer.Enabled = true;
            _timer.Start();
       }
        else
        {
            MessageBox.Show("You must logon first.");
            return;
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

private void RefreshBrowser(object sender, EventArgs e)
{
    string content = "disabled";
    string baseUrl = @"http://some url";
    string newUrl = string.Empty;
    string buttonXpath = @"/html/body/div/div[6]/table/tr/td[2]/table/tr/td/table/tr/td/table/tr[3]/td[2]/div[4]/a";
    webBrowser1.Refresh();
    _proceed = false;
    if (!content.ToLower().Equals("disabled") && !_stopped)
    {

        if (!_stopped)
        {
            HtmlAgilityPack.HtmlDocument htmlDocument = new HtmlAgilityPack.HtmlDocument();
            htmlDocument.LoadHtml(webBrowser1.DocumentText);
            HtmlNode node = htmlDocument.DocumentNode.SelectSingleNode(buttonXpath);
            content = node.GetAttributeValue("disabled", string.Empty);
            newUrl = node.GetAttributeValue("href", string.Empty);
        }
    }
    else
    {

        webBrowser1.Navigate(baseUrl + newUrl);
    }


}

private void webBrowser1_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
    _proceed = true;
    urlTextBox.Text = webBrowser1.Url.ToString();
}

private void MainPageButtonClick(object sender, EventArgs e)
{
    try
    {
        webBrowser1.Navigate(_mainPage);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

private void GoButtonClick(object sender, EventArgs e)
{
    try
    {
        webBrowser1.Navigate(urlTextBox.Text);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }

}

private void StopButtonClick(object sender, EventArgs e)
{
    _timer.Stop();
    _proceed = true;
    _stopped = true;
}

}

【问题讨论】:

    标签: c# button click


    【解决方案1】:

    您确实应该修改您的代码以使用计时器。当您滥用 GUI 线程并定期调用 Application.DoEvents(); 时,只能在该位置处理点击,这意味着您必须进入循环来处理事件。

    这绝对不能用于 GUI 编程。请改用计时器。

    Here 是一个关于如何使用计时器定期调用方法的示例。在您的情况下执行页面的刷新。

    【讨论】:

    • 我不是 100% 确定,但我认为页面有时会在加载之前刷新。
    • 是的,你是对的,将对Refresh 的调用移动到RefreshBrowser 方法的底部。应该在Navigate之后调用
    • 我还没有检查过,但是我的第一个问题已经解决了。谢谢!
    【解决方案2】:

    在我看来,这是因为您在同一个线程中执行所有内容,因此当您的代码运行时,无法进行 UI 交互(=第一次单击),而当页面重新加载时,可以进行 UI 交互(=第二次单击)。如果这是问题,请在单独的线程中执行您的刷新逻辑。

    类似:

    private void FireButtonClick(object sender, EventArgs e)
    {
        Thread worker = new Thread(new ThreadStart(delegate()
        {
            //your code
        });
        worker.IsBackground = true; //so it does not block the app from being closed
        worker.Start();
    }
    

    如果您在线程中访问 UI-Elements,您还需要使用Invoke

    【讨论】:

    • 我认为这对初学者来说太麻烦了,计时器更适合,因为它允许直接调用 GUI 元素(在 GUI 上调用)+ 需要睡眠和循环来执行重复的任务.基本上你需要重新编码一个计时器:-)
    • @jdehaan:如果您只想每 x 秒执行一次刷新,我同意,但我阅读了问题和示例以连续进行。但无论如何使用计时器会更好,因为它不会使用那么多资源并且用户体验应该差不多......
    【解决方案3】:

    我的猜测是你被困在一个 For 循环中并且在该循环完成之前无法停止。这就是为什么它似乎需要点击两次,实际上它只是在等待停止。

    尝试使用一个线程来执行网页刷新并在您的运行按钮单击中调用 thread.run() 并在您的停止按钮单击中调用 thread.stop()。由于网页刷新将在单独的线程中进行,因此不会干扰您的 UI 交互。

    【讨论】:

      猜你喜欢
      • 2022-01-21
      • 1970-01-01
      • 2020-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-29
      • 2010-09-07
      相关资源
      最近更新 更多