.net - texto - textbox c# ejemplo
.NET-Control de cuadro de texto: espere hasta que el usuario termine de escribir (6)
Declaración global de ''vb.net language''
Public Tawal as integer
''en propiedades de timer1
Timer1.enable = true
Timer1.inverval =1000
''en el procedimiento
Timer1.start()
if Tawal <2 then T awal =0
if Tawal >3 then
Call FillGrid
Timer1.stop()
end if
Saludos a todos,
¿Existe una forma integrada de saber cuándo un usuario termina de escribir en un cuadro de texto? (Antes de pulsar la pestaña, O mover el mouse) Tengo una consulta de base de datos que ocurre en el evento de cambio de texto y todo funciona perfectamente. Sin embargo, noté que hay un poco de retraso, por supuesto, porque si un usuario está escribiendo rápidamente en el cuadro de texto, el programa está ocupado haciendo una consulta para cada personaje. Así que lo que esperaba era una forma de ver si el usuario ha terminado de escribir. Así que si escriben "a" y se detienen, entonces se dispara un evento. Sin embargo, si escriben "todo el camino", el evento se dispara después de la tecla y hasta.
Tengo algunas ideas flotando alrededor de mi cabeza, pero estoy seguro de que no son las más eficientes. Al igual que medir el tiempo desde el último evento de cambio de texto y si era> más que un cierto valor, se ejecutaría el resto de mis procedimientos.
Déjame saber lo que piensas.
Idioma: VB.NET Framework: .Net 2.0
--Editado para aclarar "hecho de escribir"
Depende de lo que quieres decir con "hecho de escribir". Hay un evento para avisarle cuando el usuario ha dejado el foco de ese control en particular. Además, hay un cambio que le indica cuándo cambia el texto. Lo que podrías hacer es atrapar dos cosas:
1) enfoque perdido
2) Cada vez que el usuario cambia el texto, inicie un temporizador para, por ejemplo, 20 segundos, y si el usuario termina dentro de ese tiempo, entonces el usuario está "listo" para escribir. Es decir, si el usuario no ha hecho nada dentro de ese tiempo, suponga que el usuario está "hecho".
Si ocurre cualquiera de estas dos cosas, el usuario ha terminado, asegúrese de detener y reiniciar el temporizador adecuadamente. Obviamente, usted podría cambiar el tiempo de espera.
Todo depende de cómo quieras definirlo.
El enfoque que he utilizado con éxito en el pasado utiliza un evento de restablecimiento manual e invocaciones asíncronas para detectar cuándo el usuario ha dejado de escribir. El código se ve algo como esto
// use manual reset event to Q up waiting threads.
// each new text changed event clears the Q
// only the last changed will hit the timeout, triggering the action
private ManualResetEvent _delayMSE;
private Func<bool> TBDelay = () => !_delayMSE.WaitOne(600, false);
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
SendOrPostCallback ActionToRunWhenUserStopsTyping = o =>
{
// ...
};
_delayMSE.Set(); // open the ResetEvent gate, to discard these delays
Thread.Sleep(0); // let all pending through the gate
_delaySearchMSE.Reset(); // close the gate
TBDelay.BeginInvoke(res =>
{
// callback code
// check how we exited, via timeout or signal.
bool timedOut = TBDelay.EndInvoke(res);
if (timedOut)
Dispatcher.Invoke(DispatcherPriority.Input,
ActionToRunWhenUserStopstyping,null);
}, null);
}
Para aquellos que necesitan algo como esto en .NET 2.0, aquí hice un Control que se deriva de TextBox y usa el mismo enfoque. Espero que esta ayuda
public partial class TextBox : System.Windows.Forms.TextBox
{
private ManualResetEvent _delayMSE;
public event EventHandler OnUserStopTyping;
private delegate bool TestTimeout();
public TextBox()
{
_delayMSE = new ManualResetEvent(false);
this.TextChanged += new EventHandler(TextBox_TextChanged);
}
void TextBox_TextChanged(object sender, EventArgs e)
{
_delayMSE.Set();
Thread.Sleep(20);
_delayMSE.Reset();
TestTimeout tester = new TestTimeout(TBDelay);
tester.BeginInvoke(new AsyncCallback(Test), tester);
}
private void Test(IAsyncResult pResult)
{
bool timedOut = (bool)((TestTimeout)pResult.AsyncState).EndInvoke(pResult);
if (timedOut)
{
if (OnUserStopTyping != null)
OnUserStopTyping(this, null);
}
}
private bool TBDelay()
{
return !_delayMSE.WaitOne(500, false);
}
}
Terminé por intentar la respuesta de Scott Weinstein, aunque requería un conocimiento más profundo acerca de los hilos, los delegados y la sintaxis básica de Lambda. Y funcionó bastante bien. Su respuesta original no era simplemente copiar y pegar, así que tuve que jugar un poco para que funcionara.
Agregué muy poco tiempo a Thread.Sleep, ya que noté que el método de invocación puede ocurrir dos veces si el usuario está escribiendo muy rápido pero con un pequeño retraso aleatorio entre algunas de las pulsaciones de teclas. También debe agregar una referencia al ensamblado de WindowsBase para usar Dispatcher.
Utilizo 1,5 segundos para esperar a que el usuario termine de escribir.
// use manual reset event to Q up waiting threads.
// each new text changed event clears the Q
// only the last changed will hit the timeout, triggering the action
private ManualResetEvent _delayMSE;
private Func<bool> TBDelay;
private delegate void ActionToRunWhenUserStopstyping();
public Form1()
{
InitializeComponent();
_delayMSE = new ManualResetEvent(false);
TBDelay = () => !_delayMSE.WaitOne(1500, false);
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
_delayMSE.Set();
// open the ResetEvent gate, to discard these delays
Thread.Sleep(20);
// let all pending through the gate
_delayMSE.Reset();
// close the gate
TBDelay.BeginInvoke(res =>
{
// callback code
// check how we exited, via timeout or signal.
bool timedOut = TBDelay.EndInvoke(res);
if (timedOut)
Dispatcher.CurrentDispatcher.Invoke(
new ActionToRunWhenUserStopstyping(DoWhatEverYouNeed),
DispatcherPriority.Input);
}, null);
}
private void DoWhatEverYouNeed()
{
MessageBox.Show(textBox1.Text);
}
Una aproximación:
Crear un
Timer
con unInterval
de X milisegundosEl intervalo debe ser de unos 300ms; más de un tiempo normal entre pulsaciones de teclas, y también un tiempo razonable para esperar entre la finalización y la actualización
En el evento
TextChanged
la entrada,Stop()
y luegoTextChanged
Start()
elTimer
Esto reiniciará el
Timer
si ya se está ejecutando, por lo que si el usuario continúa escribiendo a una velocidad normal, cada cambio reiniciará el temporizador.En el evento
Tick
del temporizador,Stop()
elTimer
y haz la transacción largaOpcional:
KeyDown
eventosLeave
yKeyDown
para que al dejar el control o presionar IntroStop()
elTimer
y realice la transacción larga.
Esto causará una actualización si el texto ha cambiado, y el usuario no ha hecho ningún cambio en X milisegundos.
Un problema con el enfoque de "Medir el tiempo desde la última actualización" que está considerando es que si el último cambio se realiza rápidamente, la actualización no se realizará y no habrá ningún cambio posterior para activar otra verificación.
Nota: Debe haber un par de uno a uno entre TextBox
es y Timer
s; si planea hacer esto con más de una entrada, consideraría crear un UserControl
que envuelva esta funcionalidad.