我在 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/