Windows 8 具有文本编辑控件的功能,可在用户双击空格键后自动插入一个句点。
这可以通过“PC 设置/PC 和设备/键入/双击空格键后添加句点”设置在系统级别打开或关闭。 (此设置似乎并不总是存在 - 在我的 Surface 上存在,但在我的桌面上却不存在;我怀疑它仅在类似平板电脑的设备上可用...)
我需要能够为我正在编写的应用程序中的某个 TextBox 元素禁用此功能。
代替明显的“DisableAutoInsertPeriodsOnSpaceDoubleTap”属性,我尝试了几件事:
1) 拦截空格击键,自己插入空格并将事件标记为已处理,这样它就不会冒泡了:
private void textbox_OnKeyDown(object sender, KeyRoutedEventArgs e)
{
if (e.Key == VirtualKey.Space)
{
this.textbox.SelectedText = " ";
this.textbox.SelectionStart++;
this.textbox.SelectionLength = 0;
e.Handled = true;
}
}
这根本不会影响底层控件的行为,但是如果我用另一个字符替换空格,例如"*",则行为被抑制。
如果我尝试插入“*”然后用“”覆盖它,行为返回!
好吧,看来我无法使用该选项。
下一个想法:
2) 处理 TextChanged 事件并用空格覆盖任何自动插入的句点。
乍一看,在双击空格后,句点被插入到 SelectionStart 的左侧两个字符,所以像这样工作:
private void textbox_OnKeyDown(object sender, KeyRoutedEventArgs e)
{
this.spacePressed = e.Key == VirtualKey.Space;
}
private void textbox_TextChanged(object sender, Windows.UI.Xaml.Controls.TextChangedEventArgs e)
{
var text = this.textbox.Text;
var selectionStart = this.textbox.SelectionStart;
if (this.spacePressed && this.textbox.SelectionLength == 0 &&
selectionStart > 2 && text[selectionStart - 2] == '.')
{
// Move back two characters and overwrite the character there
this.textbox.SelectionStart -= 2;
this.textbox.SelectionLength = 1;
this.textbox.SelectedText = " ";
// Reposition the cursor back to where it was
this.textbox.SelectionStart = selectionStart;
this.textbox.SelectionLength = 0;
}
}
大获成功!...但只有当文本位于文本框的第一行时...
奇怪的是插入句点后光标位置并不总是一致的。它可以是从光标处到前面 2 个字符的任何位置。这种方法的另一个问题是,有时(我认为当光标位于句点的位置时)用空格替换句点会导致系统锁定,底层控件用句号替换空格,我的代码用空格替换它,来回无限循环。
这个问题的最佳结果是我可以在某处设置一个简单的属性,我浪费了一个小时来解决这个问题。有人吗?
最佳答案
第一次尝试的变体起作用了——用“空格替代”替换空格,例如一个不间断的空间,足以绕过句点插入:
private void textbox_OnKeyDown(object sender, KeyRoutedEventArgs e)
{
if (e.Key == VirtualKey.Space)
{
// Spaces are always output as non-breaking spaces
this.textbox.SelectedText = "\u00A0";
this.textbox.SelectionStart++;
this.textbox.SelectionLength = 0;
e.Handled = true;
}
}
然后我在返回源代码的绑定(bind)之上添加了一个转换器,确保在返回的路上将不间断空格替换为正常空格:
public class SpaceReplaceConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
var text = value as string;
return text != null ? text.Replace(' ', '\u00A0') : value;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
var text = value as string;
return text != null ? text.Replace('\u00A0', ' ') : value;
}
}
这样使用:
<TextBox Text="{Binding Text, Mode=TwoWay, Converter={StaticResource SpaceReplaceConverter}}" />
希望对其他人有帮助。
关于c# - 为 winrt 文本框禁用 "double tap space for period",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23978823/