2010-06-24 38 views
8

Tôi có một số TextBox với sự kiện TextChanged được kết nối. Cuối cùng nó đang thực hiện một truy vấn đến một cơ sở dữ liệu SQL, vì vậy tôi muốn giới hạn số lượng truy vấn.Làm cách nào để xử lý sự kiện TextChanged chỉ khi người dùng ngừng nhập?

Tôi chỉ muốn thực hiện truy vấn nếu người dùng chưa nhấn phím trong ví dụ: 300 mili giây hoặc lâu hơn. Nếu vì một lý do nào đó truy vấn trước đó vẫn đang thực thi, tôi sẽ cần phải hủy bỏ nó, và sau đó đưa ra một truy vấn mới.

Trả lời

8

Tạo System.Windows.Forms.Timer và đặt lại (ví dụ: dừng sau đó khởi động) sau mỗi lần nhấn phím. Nếu sự kiện hẹn giờ được kích hoạt, hãy vô hiệu hóa bộ hẹn giờ.

+0

Đây là phương pháp tôi đã sử dụng và nó hoạt động hoàn hảo. Đáng ngạc nhiên là tôi không nhận được bất kỳ ngoại lệ nào về giao diện người dùng đang được cập nhật bởi một chuỗi khác? – esac

+0

Xem http://msdn.microsoft.com/en-us/magazine/cc164015.aspx#S1. Câu trả lời ngắn gọn là sự kiện được thực thi trong chuỗi giao diện người dùng. Điều này có ý nghĩa, cho rằng nó nằm trong không gian tên 'System.Windows.Forms'. – Brian

+0

Lưu ý rằng liên kết tạp chí MSDN ở trên không còn là liên kết trực tiếp nữa. Bạn vẫn có thể truy cập nó bằng [archive.org] (https://web.archive.org/web/20130219050936/http://msdn.microsoft.com/en-us/magazine/cc164015.aspx). Hoặc, chỉ cần tải xuống tạp chí tháng 2 năm 2004 từ trang đó. Nếu bạn không có trình đọc CHM, bạn có thể truy cập bài viết bằng cách giải nén tệp CHM bằng cách sử dụng 7zip và mở '/ MSDNMagazineFebruary2004en-us/TimersinNET/chm.htm' – Brian

0

Thêm một trình xử lý tác vụ thứ hai được gọi bất cứ khi nào người dùng nhấn phím bất kỳ và khi được gọi là lưu thời gian hiện tại vào biến toàn cầu. Sau đó, khi sự kiện TextChanged của bạn được gọi, nó sẽ kiểm tra để xem chênh lệch thời gian giữa biến toàn cầu và thời gian hiện tại.

Nếu chênh lệch nhỏ hơn 300 mili giây thì hãy bắt đầu bộ hẹn giờ để thực hiện truy vấn sau 300 mili giây. Sau đó, nếu người dùng nhấn một khóa khác, nó sẽ đặt lại bộ hẹn giờ trước.

+0

Điều này yêu cầu người dùng đợi 300ms và sau đó nhập một ký tự khác nếu họ muốn gửi kết quả. – Brian

1

Sử dụng Khung phản ứng để kích hoạt trên một chuỗi các sự kiện. Tôi không chắc chắn chính xác cách thức này hoạt động, nhưng bạn có thể đọc ở đây (Reactive Extensions for .NET) và xem liệu nó có đáp ứng được nhu cầu của bạn hay không. Có một loạt các ví dụ ở đây: Examples. Ví dụ "Điều chỉnh" có thể là những gì bạn đang tìm kiếm.

0

1) Tạo bộ hẹn giờ.

2) Tạo trình xử lý cho sự kiện Tick của bộ hẹn giờ. Trên mỗi đánh dấu, kiểm tra để xem nếu đủ thời gian nhàn rỗi đã trôi qua, và nếu nó có, DỪNG bộ đếm thời gian và thực hiện truy vấn.

3) Bất cứ khi nào nhấn phím xuất hiện trên hộp văn bản đó, RESTART bộ hẹn giờ.

1

Nhờ ý tưởng của @ Brian và this answer, tôi đã đưa ra phiên bản sử dụng bộ hẹn giờ để xử lý vấn đề này. Điều này làm việc tốt cho tôi. Tôi hy vọng nó cũng sẽ giúp những người khác:

private Timer _tmrDelaySearch; 
private const int DelayedTextChangedTimeout = 500; 
private void txtSearch_TextChanged(object sender, EventArgs e) 
{ 
    if (_tmrDelaySearch != null) 
    _tmrDelaySearch.Stop(); 

    if (_tmrDelaySearch == null) 
    { 
     _tmrDelaySearch = new Timer(); 
     _tmrDelaySearch.Tick += _tmrDelaySearch_Tick; 
     _tmrDelaySearch.Interval = DelayedTextChangedTimeout; 
    } 

    _tmrDelaySearch.Start(); 
} 

void _tmrDelaySearch_Tick(object sender, EventArgs e) 
{ 
    if (stcList.SelectedTab == stiTabSearch) return; 
    string word = string.IsNullOrEmpty(txtSearch.Text.Trim()) ? null : txtSearch.Text.Trim(); 

    if (stcList.SelectedTab == stiTabNote) 
    FillDataGridNote(word); 
    else 
    { 
     DataGridView dgvGridView = stcList.SelectedTab == stiTabWord ? dgvWord : dgvEvent; 
     int idType = stcList.SelectedTab == stiTabWord ? 1 : 2; 
     FillDataGrid(idType, word, dgvGridView); 
    } 

    if (_tmrDelaySearch != null) 
    _tmrDelaySearch.Stop(); 
} 
Các vấn đề liên quan