Tôi có một biểu mẫu chứa một TextBox
trong C # mà tôi đặt thành một chuỗi như sau:
textBox.Text = str;
Khi biểu mẫu được hiển thị, tại sao văn bản trong hộp thư lại được đánh dấu / chọn?
Tôi có một biểu mẫu chứa một TextBox
trong C # mà tôi đặt thành một chuỗi như sau:
textBox.Text = str;
Khi biểu mẫu được hiển thị, tại sao văn bản trong hộp thư lại được đánh dấu / chọn?
Câu trả lời:
Hộp văn bản có TabIndex
0 và TabStop
được đặt thành true. Điều này có nghĩa là điều khiển sẽ được tập trung khi biểu mẫu được hiển thị.
Bạn có thể đặt một điều khiển khác là 0 TabIndex
(nếu có) và cung cấp cho hộp văn bản một chỉ mục tab khác (> 0) hoặc đặt TabStop
thành false cho hộp văn bản để ngăn điều này xảy ra.
Hành vi mặc định của TextBox trong Windows Forms là đánh dấu tất cả văn bản nếu nó được tập trung lần đầu tiên bằng cách nhấn tab vào nó, nhưng không đánh dấu nếu nó được nhấp vào. Chúng ta có thể thấy điều này trong Reflector bằng cách xem phần ghi đè TextBox
của 's OnGotFocus()
:
protected override void OnGotFocus(EventArgs e)
{
base.OnGotFocus(e);
if (!this.selectionSet)
{
this.selectionSet = true;
if ((this.SelectionLength == 0) && (Control.MouseButtons == MouseButtons.None))
{
base.SelectAll();
}
}
}
Đó là câu lệnh if gây ra hành vi mà chúng ta không thích. Hơn nữa, để thêm sự xúc phạm đến thương tích, người thiết lập Text
tài sản đặt lại một cách mù quáng selectionSet
biến đó bất cứ khi nào văn bản được gán lại:
public override string Text
{
get
{
return base.Text;
}
set
{
base.Text = value;
this.selectionSet = false;
}
}
Vì vậy, nếu bạn có TextBox và tab trong đó, tất cả văn bản sẽ được chọn. Nếu bạn nhấp vào nó, phần đánh dấu sẽ bị xóa và nếu bạn nhấn lại vào nó, vị trí dấu mũ của bạn (và độ dài lựa chọn bằng 0) sẽ được giữ nguyên. Nhưng nếu chúng ta lập trình đặt mới Text
và tab vào TextBox một lần nữa, thì tất cả văn bản sẽ được chọn lại.
Nếu bạn giống tôi và thấy hành vi này gây phiền nhiễu và không nhất quán, thì có hai cách để giải quyết vấn đề này.
Đầu tiên, và có lẽ là dễ nhất, chỉ cần kích hoạt cài đặt selectionSet
bằng cách gọi DeselectAll()
vào biểu mẫu Load()
và bất cứ khi nào Text
thay đổi:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this.textBox2.SelectionStart = this.textBox2.Text.Length;
this.textBox2.DeselectAll();
}
( DeselectAll()
Chỉ bộ SelectionLength
không. Nó thực sự SelectionStart
mà flips TextBox
's selectionSet
biến. Trong trường hợp trên, các cuộc gọi đến DeselectAll()
là không cần thiết vì chúng ta đang thiết lập khi bắt đầu đến khi kết thúc của văn bản. Nhưng nếu chúng ta đặt nó vào bất kỳ vị trí khác, như đầu văn bản, sau đó gọi nó là một ý kiến hay.)
Cách lâu dài hơn là tạo TextBox của riêng chúng tôi với hành vi mong muốn thông qua kế thừa:
public class NonSelectingTextBox : TextBox
{
// Base class has a selectionSet property, but its private.
// We need to shadow with our own variable. If true, this means
// "don't mess with the selection, the user did it."
private bool selectionSet;
protected override void OnGotFocus(EventArgs e)
{
bool needToDeselect = false;
// We don't want to avoid calling the base implementation
// completely. We mirror the logic that we are trying to avoid;
// if the base implementation will select all of the text, we
// set a boolean.
if (!this.selectionSet)
{
this.selectionSet = true;
if ((this.SelectionLength == 0) &&
(Control.MouseButtons == MouseButtons.None))
{
needToDeselect = true;
}
}
// Call the base implementation
base.OnGotFocus(e);
// Did we notice that the text was selected automatically? Let's
// de-select it and put the caret at the end.
if (needToDeselect)
{
this.SelectionStart = this.Text.Length;
this.DeselectAll();
}
}
public override string Text
{
get
{
return base.Text;
}
set
{
base.Text = value;
// Update our copy of the variable since the
// base implementation will have flipped its back.
this.selectionSet = false;
}
}
}
Bạn có thể bị cám dỗ để không gọi base.OnGotFocus()
, nhưng sau đó chúng ta sẽ mất chức năng hữu ích trong Control
lớp cơ sở . Và bạn có thể bị cám dỗ để không gây rối với những selectionSet
điều vô nghĩa và chỉ cần bỏ chọn văn bản mọi lúc trong OnGotFocus (), nhưng sau đó chúng tôi sẽ mất điểm nổi bật của người dùng nếu họ tab ra khỏi trường và quay lại.
Xấu xí? Bạn betcha. Nhưng đó là những gì nó được.
Các câu trả lời cho câu hỏi này đã giúp tôi rất nhiều với một vấn đề tương tự, nhưng câu trả lời đơn giản chỉ được gợi ý cùng với rất nhiều gợi ý phức tạp khác. Chỉ cần đặt SelectionStart
thành 0
sau khi đặt Văn bản của bạn. Vấn đề đã được giải quyết!
Thí dụ:
yourtextbox.Text = "asdf";
yourtextbox.SelectionStart = 0;
Bạn cũng có thể chọn thứ tự tab cho các điều khiển biểu mẫu của mình bằng cách mở:
Xem-> Thứ tự tab
Lưu ý rằng tùy chọn này chỉ khả dụng trong "Chế độ xem" nếu bạn mở chế độ xem thiết kế Biểu mẫu.
Chọn "Thứ tự tab" sẽ mở ra dạng xem Biểu mẫu cho phép bạn chọn thứ tự tab mong muốn bằng cách nhấp vào các điều khiển.
Để hiển thị trường văn bản, với VS 2013, hãy thử bắt đầu bằng:
myTextBox.GotFocus += new System.EventHandler(this.myTextBox_GotFocus);
Và thêm phương thức:
public void myTextBox_GotFocus(object sender, EventArgs e)
{
myTextBox.SelectionLength=0;
}
Tôi chưa thử nghiệm điều này trên C # nhưng tôi đã gặp phải vấn đề tương tự khi sử dụng hộp thoại C ++ WIN32. Có vẻ như bạn có thể thay đổi hành vi bằng cách quay lại FALSE
từ OnInitDialog()
hoặc WM_INITDIALOG
. Hi vọng điêu nay co ich.