C#温度转换器

时间:2017-04-28 02:23:39

标签: c#

我正在尝试创建一个温度转换器,一切都很好。

    private void hsbTemperature_Scroll(object sender, ScrollEventArgs e)
    {
        TempFah = hsbTemperature.Value;
        txtCelsius.Text = Convert.ToString(TempFah);
        TempCel = Convert.ToInt32((TempFah - 32) * 5 / 9);
        txtFahrenheit.Text = TempCel.ToString();
    }

    private void hsbTemperature_ValueChanged(object sender, EventArgs e)
    {
        TempFah = hsbTemperature.Value;
        txtCelsius.Text = Convert.ToString(TempFah);
        TempCel = Convert.ToInt32((TempFah - 32) * 5 / 9);
        txtFahrenheit.Text = TempCel.ToString();
    }
}

但是,当我尝试更改华氏度文本框的值时,摄氏度文本框的值不会更改,反之亦然。两个文本框的值仅在我移动滚动条时更改。

所以我需要的是,当我改变华氏温度的值时,我希望摄氏度的值也会改变,反之亦然。

请帮助,谢谢。

1 个答案:

答案 0 :(得分:2)

这就是我要做的事情:

看起来您已经定义了这些类级属性:

private int TempFah;
private int TempCel;

此外,您无需在Scroll事件中添加任何代码。 ValueChanged确实是我们关心的问题,无论如何都会在Scroll之后立即调用。

private void hsbTemperature_Scroll(object sender, ScrollEventArgs e)
{
    // Don't use this method when you really care about the value
}

因此,我们不会在任何触发对方的属性更改事件的无限循环中结束,我创建了一个私有bool变量来跟踪我们是否以编程方式更新文本字段(相反)给用户这样做)。如果将其设置为true,那么我们不需要处理更改事件中的任何代码,因为UpdateTempFields方法(即将出现)已经在执行它。

private bool programIsUpdatingProperties = false;

为了帮助将代码分离成可重复使用的部分,我们可以创建一个单独的函数来从华氏温度值中获取Celsius值。虽然我们正在努力,但要做出相反的事情:

private int GetCelciusValue(int fahrenheitValue)
{
    return (fahrenheitValue - 32) * 5 / 9;
}

private int GetFahrenheitValue(int celsiusValue)
{
    return celsiusValue * 9 / 5 + 32;
}

现在是时候创建UpdateTempFields方法,在给定华氏温度的情况下,该方法知道如何更新表单上的所有控制值。

确保我们不会过度设置hsbTemperature.Value(用户可以输入太大或太小)的一个技巧是使用hsbTemperature.Maximum或数字中最小的一个,为了确保我们不设置它,我们得到hsbTemperature.Minimum或数字的最大值。以下使用下面的Math.MaxMath.Min完成此操作:

private void UpdateTempFields(int newFahrenheitTemp)
{
    // Let the rest of the code know this is us, not the user
    programIsUpdatingProperties = true;

    TempFah = newFahrenheitTemp;
    TempCel = GetCelciusValue(TempFah);

    txtCelsius.Text = TempCel.ToString();
    txtFahrenheit.Text = TempFah.ToString();

    // Ensure we don't try to set the scroll bar to a value it can't handle
    hsbTemperature.Value =
        Math.Max(hsbTemperature.Minimum,
            Math.Min(hsbTemperature.Maximum, TempFah));

    // Carry on as normal now...
    programIsUpdatingProperties = false;
}

现在,在我们控件的更改事件中,我们所要做的就是使用华氏度值调用UpdateTempFields()方法,它将处理其余的事情。但是如果用户是更改值的用户,我们只想这样做,所以首先检查我们的标志:

private void txtFahrenheit_TextChanged(object sender, EventArgs e)
{
    if (!programIsUpdatingProperties)
    {
        int fahrValue;
        // Use int.TryParse to ensure it's a valid integer (if it's not, do nothing)
        if (int.TryParse(txtFahrenheit.Text, out fahrValue))
        {
            UpdateTempFields(fahrValue);
        }
    }
}

private void txtCelsius_TextChanged(object sender, EventArgs e)
{
    if (!programIsUpdatingProperties)
    {
        int celsiusValue;
        // Use int.TryParse to ensure it's a valid integer (if it's not, do nothing)
        if (int.TryParse(txtCelsius.Text, out celsiusValue))
        {
            // Convert celcius to fahrenheit first
            var fahrValue = GetFahrenheitValue(celsiusValue);
            UpdateTempFields(fahrValue);
        }
    }
}

private void hsbTemperature_ValueChanged(object sender, EventArgs e)
{
    if (!programIsUpdatingProperties)
    {
        UpdateTempFields(hsbTemperature.Value);
    }
}