为winrt文本框禁用“双击时间段”

时间:2014-06-01 10:19:32

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

Windows 8具有文本编辑控件功能,可在用户双击空格键后自动插入句点。

可以在系统级别通过&#34; PC设置/ PC和设备打开或关闭此功能/打字/在我双击空格键后添加一段时间&#34;设置。 (这个设置似乎总是在那里 - 在我的Surface上它是,在我的桌面上它不是;我怀疑它只能在类似平板电脑的设备上使用......)< / p>

我需要能够在我正在编写的应用中为某个TextBox元素禁用此功能。

代替显而易见的&#34; DisableAutoInsertPeriodsOnSpaceDoubleTap&#34;财产,我尝试了几件事:

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

这根本不会影响底层控件的行为,但是如果我用另一个字符替换空格,例如&#34; *&#34;,然后行为抑制。

如果我尝试插入&#34; *&#34;然后使用&#34; 覆盖它&#34;,行为返回

好的,所以我看起来没有能力使用该选项。

接下来想:

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个字符的任何位置。这种方法的另一个问题是有时(我认为当光标期间的位置时)用空格替换句点会导致系统锁定,底层控件用句号替换空格,我的代码用空格替换,并且无限制地来回替换。

这个问题的最好结果是,我可以设置一个简单的属性,而且我浪费了一个小时搞乱这个。任何人吗?

1 个答案:

答案 0 :(得分:0)

第一次尝试的变体有效 - 用空间替换&#34;替换空格,例如一个不间断的空间,足以绕过句号插入:

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

希望能帮助别人。