【问题标题】:Visual Studio 2019 event handling issue [duplicate]Visual Studio 2019 事件处理问题 [重复]
【发布时间】:2020-10-28 05:36:27
【问题描述】:

在 Visual Studio 2019 中,我正在创建一个转换不同测量单位的程序,它的作用是,如果我输入英尺的数字,它会使用英尺中使用的数字计算其余单位。在我的程序中,前四个函数有效,但当我尝试输入最后四个函数时应用程序冻结。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ConversionLenUnit
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void txtMeter_TextChanged(object sender, EventArgs e)
        {
            txtMillimeter.Text = $"{double.Parse(txtMeter.Text) * 1000}";
            txtCentimeter.Text = $"{double.Parse(txtMeter.Text) * 100}";
            txtKilometer.Text = $"{double.Parse(txtMeter.Text) / 1000}";
            txtInch.Text = $"{double.Parse(txtMeter.Text) * 39.37}";
            txtYard.Text = $"{double.Parse(txtMeter.Text) * 1.0936}";
            txtFoot.Text = $"{double.Parse(txtMeter.Text) * 3.28}";
            txtMile.Text = $"{double.Parse(txtMeter.Text) * 0.00062137}";
        }

        private void txtMillimeter_TextChanged(object sender, EventArgs e)
        {
            txtMeter.Text = $"{double.Parse(txtMillimeter.Text) / 1000}";
            txtCentimeter.Text = $"{double.Parse(txtMillimeter.Text)/ 10}";
            txtKilometer.Text = $"{double.Parse(txtMillimeter.Text) / 1000000}";
            txtInch.Text = $"{double.Parse(txtMillimeter.Text) / 25.4}";
            txtYard.Text = $"{double.Parse(txtMillimeter.Text) / 914}";
            txtFoot.Text = $"{double.Parse(txtMillimeter.Text) / 305}";
            txtMile.Text = $"{double.Parse(txtMillimeter.Text) * 0.00000062137}";
        }

        private void txtCentimeter_TextChanged(object sender, EventArgs e)
        {
            txtMeter.Text = $"{double.Parse(txtCentimeter.Text) / 100}";
            txtMillimeter.Text = $"{double.Parse(txtCentimeter.Text) * 10}";
            txtKilometer.Text = $"{double.Parse(txtCentimeter.Text) / 100000}";
            txtInch.Text = $"{double.Parse(txtCentimeter.Text) / 2.54}";
            txtYard.Text = $"{double.Parse(txtCentimeter.Text) / 91.44}";
            txtFoot.Text = $"{double.Parse(txtCentimeter.Text) / 30.48}";
            txtMile.Text = $"{double.Parse(txtCentimeter.Text) / 160934}";
        }

        private void txtKilometer_TextChanged(object sender, EventArgs e)
        {
            txtMeter.Text = $"{double.Parse(txtKilometer.Text) * 1000}";
            txtMillimeter.Text = $"{double.Parse(txtKilometer.Text) / 0.000001}";
            txtCentimeter.Text = $"{double.Parse(txtKilometer.Text) * 100000}";
            txtInch.Text = $"{double.Parse(txtKilometer.Text) * 39370}";
            txtYard.Text = $"{double.Parse(txtKilometer.Text) * 1094}";
            txtFoot.Text = $"{double.Parse(txtKilometer.Text) * 3281}";
            txtMile.Text = $"{double.Parse(txtKilometer.Text) / 1.609}";
        }

        private void txtInch_TextChanged(object sender, EventArgs e)
        {
            //txtMeter.Text = $"{double.Parse(txtInch.Text) / 39.37}";
            //txtMillimeter.Text = $"{double.Parse(txtInch.Text) * 25.4}";
            //txtCentimeter.Text = $"{double.Parse(txtInch.Text) * 2.54}";
            //txtKilometer.Text = $"{double.Parse(txtInch.Text) / 39370}";
            //txtYard.Text = $"{double.Parse(txtInch.Text) / 36}";
            //txtFoot.Text = $"{double.Parse(txtInch.Text) / 12}";
            //txtMile.Text = $"{double.Parse(txtInch.Text) / 63360}";
        }

        private void txtYard_TextChanged(object sender, EventArgs e)
        {
            //txtMeter.Text = $"{double.Parse(txtYard.Text) / 1.094}";
            //txtMillimeter.Text = $"{double.Parse(txtYard.Text) * 914}";
            //txtCentimeter.Text = $"{double.Parse(txtYard.Text) * 91.44}";
            //txtKilometer.Text = $"{double.Parse(txtYard.Text) / 1094}";
            //txtInch.Text = $"{double.Parse(txtYard.Text) * 36}";
            //txtFoot.Text = $"{double.Parse(txtYard.Text) * 3}";
            //txtMile.Text = $"{double.Parse(txtYard.Text) / 1760}";
        }

        private void txtFoot_TextChanged(object sender, EventArgs e)
        {
            //txtMeter.Text = $"{double.Parse(txtFoot.Text) / 3.281}";
            //txtMillimeter.Text = $"{double.Parse(txtFoot.Text) * 305}";
            //txtCentimeter.Text = $"{double.Parse(txtFoot.Text) * 30.48}";
            //txtKilometer.Text = $"{double.Parse(txtFoot.Text) / 3281}";
            //txtInch.Text = $"{double.Parse(txtFoot.Text) * 12}";
            //txtYard.Text = $"{double.Parse(txtFoot.Text) / 3}";
            //txtMile.Text = $"{double.Parse(txtFoot.Text) / 5280}";
        }

        private void txtMile_TextChanged(object sender, EventArgs e)
        {
            //txtMeter.Text = $"{double.Parse(txtMile.Text) * 1609}";
            //txtMillimeter.Text = $"{double.Parse(txtMile.Text) * 1609344}";
            //txtCentimeter.Text = $"{double.Parse(txtMile.Text) * 160934}";
            //txtKilometer.Text = $"{double.Parse(txtMile.Text) * 1.609}";
            //txtInch.Text = $"{double.Parse(txtMile.Text) * 63360}";
            //txtYard.Text = $"{double.Parse(txtMile.Text) * 1760}";
            //txtFoot.Text = $"{double.Parse(txtMile.Text) * 5280}";
        }
    }
}

【问题讨论】:

  • 如果您设置两个事件处理程序,其模式如下:“当 A 更改时,更改 B”。和“当B改变时,改变A”。这本质上是一个无限循环。
  • OT 建议清理:每个处理程序使用 double.Parse 一次(带错误检查),然后在下一行使用该结果
  • 这一点的重要方面是,由于浮点精度,计算的最后几个数字可能会发生翻转。如果文本没有改变,它实际上不会触发 TextChanged 事件。您可以添加一些日志消息来确认这一点。
  • 为了将来参考,请在向本网站发布另一个问题之前阅读How to Askminimal reproducible example。您的问题本质上是这里已经存在的其他问题的副本(标记的副本是针对 WPF,但相同的原则仍然适用于 Winforms),但问题本身的质量很差。社区在回答问题上投入了大量精力;发布问题的人应该至少投入同样多的精力来编写问题。

标签: c# visual-studio


【解决方案1】:

毫无疑问,您在处理第一个事件的同时导致另一个事件触发,然后它导致另一个事件在无限循环中触发。您应该能够在调试器中看到这一点。

解决方案是在您的类中添加一个布尔值,以跟踪您是否正在处理事件。如果该布尔值为 true,则每个事件处理程序都需要提前执行 return

检查是否为true后,设置为true,做完事件处理器的所有工作,最后设置为false

例如,

private bool changing = false;

private void txtMeter_TextChanged(object sender, EventArgs e)
{
   if (changing) return;

   changing = true;

   // do all the work

   changing = false;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多