【问题标题】:Disable "double tap space for period" for winrt textbox为winrt文本框禁用“双击空格”
【发布时间】:2014-06-02 20:15:04
【问题描述】:

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 个字符的任意位置。这种方法的另一个问题是 sometimes(我认为当光标 句点的位置时)用空格替换句点会导致系统锁定,与底层控件将空格替换为句点,我的代码将其替换为空格,然后无限循环。

这个问题的最佳结果是我可以在某个地方设置一个简单的属性,我浪费了一个小时来搞砸这个。有人吗?

【问题讨论】:

    标签: c# xaml windows-store-apps winrt-xaml


    【解决方案1】:

    第一次尝试的变体 - 用“空格替代”替换空格,例如一个不间断的空格,足以绕过句号插入:

    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;
        }
    }
    

    然后我在绑定到源代码的顶部添加了一个转换器,确保在返回的途中将不间断空格替换为正常空格:

    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}}" />
    

    希望对其他人有所帮助。

    【讨论】:

      猜你喜欢
      • 2011-02-04
      • 1970-01-01
      • 1970-01-01
      • 2021-09-30
      • 2015-10-07
      • 2011-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多