c# - 多次触发事件 TextChanged

标签 c# wpf windows-phone-8 windows-phone

我在 Windows Phone 上的应用程序中有三个 TextBox。我想在用户在其中任何一个中插入输入后立即更改这三个 TextBox 的数值。

我的 xaml 看起来像这样:

<TextBox x:Name="t_horizontal" InputScope="Number" TextChanged="cambio"/>
<TextBox x:Name="t_vertical" InputScope="Number" TextChanged="cambio" />
<TextBox x:Name="t_diagonal" InputScope="Number" TextChanged="cambio"/>

我在 C# 中的代码是:

private void cambio(object sender, TextChangedEventArgs e)
{
    TextBox modificado = sender as TextBox;
    if (modificado.Name == "t_horizontal")
    {
        this.ancho = Double.Parse(modificado.Text);
        this.diagonal = getDiagonal(this.ancho, this.alto);
    } 
    else if (modificado.Name == "t_vertical")
    {
        this.alto = Double.Parse(modificado.Text);
        this.diagonal = getDiagonal(this.ancho,this.alto);
    }
    else if (modificado.Name == "t_diagonal")
    {
        this.diagonal = Double.Parse(modificado.Text);
        this.ancho = getAncho(diagonal);
        this.alto = getAlto(diagonal);
    }
    t_vertical.Text = this.alto+"";
    t_horizontal.Text = this.ancho+"";
    t_diagonal.Text = this.diagonal+"";
}

我猜想当我为 TextBoxes 分配一个新值时,事件再次被触发,并且我的代码进入无限循环。 我究竟做错了什么?我该如何解决这个问题?

最佳答案

您处于无限循环中,因为您更改了 TextChanged 事件中的文本,所以它会再次触发它。 Rohit Vats answer不会工作,因为 TextChanged event异步的 - 所以你的情况是活泼的。为了更好地了解它是如何工作的,我通过添加 SempahoreSlim 并等待其他事件完成来改进 Rohit 的答案。另一个问题是事件仅在值更改时引发,因此我们必须检查是否等待信号量。

private bool textChanged = false;
SemaphoreSlim sem = new SemaphoreSlim(0, 1);
private async void cambio(object sender, TextChangedEventArgs e)
{
    if (!textChanged)
    {
        TextBox modificado = sender as TextBox;
        if (modificado.Name == "t_horizontal")
        {
            this.ancho = Double.Parse(modificado.Text);
            this.diagonal = getDiagonal(this.ancho, this.alto);
        }
        else if (modificado.Name == "t_vertical")
        {
            this.alto = Double.Parse(modificado.Text);
            this.diagonal = getDiagonal(this.ancho, this.alto);
        }
        else if (modificado.Name == "t_diagonal")
        {
            this.diagonal = Double.Parse(modificado.Text);
            this.ancho = getAncho(diagonal);
            this.alto = getAlto(diagonal);
        }
        textChanged = true;
        if (t_vertical.Text != this.alto + "")
        {
            t_vertical.Text = this.alto + "";
            await sem.WaitAsync(); // wait until finished changing with skip (flag)
        }
        if (t_horizontal.Text != this.ancho + "")
        {
            t_horizontal.Text = this.ancho + "";
            await sem.WaitAsync(); // wait until finished changing with skip (flag)
        }
        if (t_diagonal.Text != this.diagonal + "")
        {
            t_diagonal.Text = this.diagonal + "";
            await sem.WaitAsync(); // wait until finished changing with skip (flag)
        }
        textChanged = false;
    }
    else sem.Release();
}

上面的代码是脏的,但应该显示正在发生的事情(不要使用它 - 它只是一个例子),调试并使用它。

您还可以尝试通过取消订阅/订阅事件来使其更简单:

private void cambio(object sender, TextChangedEventArgs e)
{
    TextBox modificado = sender as TextBox;
    if (modificado.Name == "t_horizontal")
    {
        this.ancho = Double.Parse(modificado.Text);
        this.diagonal = getDiagonal(this.ancho, this.alto);
    }
    else if (modificado.Name == "t_vertical")
    {
        this.alto = Double.Parse(modificado.Text);
        this.diagonal = getDiagonal(this.ancho, this.alto);
    }
    else if (modificado.Name == "t_diagonal")
    {
        this.diagonal = Double.Parse(modificado.Text);
        this.ancho = getAncho(diagonal);
        this.alto = getAlto(diagonal);
    }
    t_vertical.TextChanged -= cambio;
    t_horizontal.TextChanged -= cambio;
    t_diagonal.TextChanged -= cambio;
    t_vertical.Text = this.alto + "";
    t_horizontal.Text = this.ancho + "";
    t_diagonal.Text = this.diagonal + "";
    t_vertical.TextChanged += cambio;
    t_horizontal.TextChanged += cambio;
    t_diagonal.TextChanged += cambio;
}

当然,您的代码可能应该修改以防止出现这种情况。

关于c# - 多次触发事件 TextChanged,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22944913/

相关文章:

c# - Entity Framework 4 中的左外连接太多了吗?

c# - Windows服务中Application.ExecutablePath的等价物是什么

c# - 带有 winforms 部署的 sqlite 数据库

c# - 拥有无限工作线程的正确方法?

c# - 为什么MVVMLight的RelayCommand使用WeakAction

c# - 如何以编程方式检查 WP8 设备是否有前置摄像头

wpf - 如何在wpf工具包中动态添加更多线系列到折线图中?

wpf - 在 WPF ListBox 中访问 ListBoxItem-Controls

android - Windows Phone 8 和 Android 可以通过 Wifi Direct 连接吗?

c# - 像在 Xcode 中一样在 visual studio 中有 Storyboard?