我遇到了一个简单的控制处理程序在该处理程序中被调用的情况,这对我来说不是一个新问题,但我的简单解决方案没有通过代码审查。我搜索了类似的SO问题,发现了几个类似的问题,但我不确定它们是否是最好的解决方案。
我在网格控件上有一个简单的文本框,用于搜索数据网格中显示的大型数据集中的行。计划是使用回车作为搜索的触发器,因此" AcceptsReturn"被设定为" True"在文本框中。简单的MainWindow.xaml:
<Window x:Class="TestXaml.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="100" Width="250">
<Grid x:Name="LayoutRoot" Background="White" Height="100" Width="200">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="60" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="80" />
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Name="GoToLabel" Content="Go To Packet ID:" Margin="12, 0, 0, 0"/>
<TextBox Grid.Row="0" Grid.Column="1" Name="GoToTarget" Width="75" TextChanged="GoToTarget_TextChanged" AcceptsReturn="True"/>
</Grid>
MainWindow.xaml.cs:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
namespace TestXaml
{
class SomeDataViewModel
{
public SomeDataViewModel() { }
public bool PacketIndexFor(int packetId, ref int packetIndex)
{
packetIndex = packetId; // Just a dummy.
return true;
}
}
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow :
{
private SomeDataViewModel someDataViewModel; // The data viewmodel.
private bool inGoToTarget = false; // Stop recursion into goToTarget_TextChanged.
public MainWindow()
{
InitializeComponent();
}
private void GoToTarget_TextChanged(object sender, TextChangedEventArgs e)
{
if (inGoToTarget) // If we are already handling a text-changed event, get out.
{
return;
}
inGoToTarget = true;
TextBox goToTarget = sender as TextBox;
if (null == goToTarget)
{
inGoToTarget = false
return;
}
if (String.IsNullOrEmpty(goToTarget.Text))
{
inGoToTarget = false;
return;
}
string enteredTextNoReturn = goToTarget.Text;
if (-1 != goToTarget.Text.IndexOf("\r\n"))
{
enteredTextNoReturn = goToTarget.Text.Substring(0, goToTarget.Text.Length - 2); // Strip "\r\n"
}
if (String.IsNullOrEmpty(enteredTextNoReturn)) // Was just carriage return.
{
// Next line will cause a call to GoToTarget_TextChanged from inside GoToTarget_TextChanged.
goToTarget.Text = ""; // Get rid of carriage return.
inGoToTarget = false;
return;
}
goToTarget.Text = enteredTextNoReturn; // Get rid of the carriage return.
int packetId = -1;
if (int.TryParse(enteredTextNoReturn, out packetId))
{
int packetIndex = -1;
if (someDataViewModel.PacketIndexFor(packetId, ref packetIndex))
{
// Set a slider or control value that will make the requested packet display.
}
}
inGoToTarget = false;
}
}
}
注意到&#34;解决&#34;我的问题,我刚给课程添加了一个bool,&#34; inGoToTarget&#34;并设置/取消设置它,以便如果我在处理程序中并尝试重新输入它,处理程序将只返回。
意识到重新进入处理程序的调用发生在处理程序内部,因此在同一个线程中,使用.Net 4.5或更高版本避免此问题的最佳实践方法是什么?
我&#34;修复&#34;通过完全避免它 - 我决定在输入数字时我喜欢发生的行为,所以刚刚删除了&#34; AcceptsReturn&#34;属性。这意味着我可以删除检查回车的代码,并避免在处理程序内设置值。