2013-04-10 108 views
2

长时间监听,第一次来电。我对WinRT C#/ XAML中的TextBox有一个奇怪的问题,我希望有人能够帮助我。第二个文本框显示与第一个相同的文本选择

基本上,我正在创建一个自定义控件,基本上需要第二个TextBox是第一个的副本,包括显示相同的文本,并显示相同的选定文本。很显然,对于文本要求,我只是简单地回应第一个文本框的TextChanged事件,并将第二个文本框的文本从第一个文本设置为Text,这很好。

选定文本要求我开始用类似的解决方案,而我对这个代码如下:

void TextBox1_SelectionChanged(object sender, RoutedEventArgs e) 
    { 
     this.TextBox2.Select(this.TextBox1.SelectionStart, this.TextBox1.SelectionLength); 
    } 

这似乎工作时,最初使用鼠标很好:

screen cap using mouse

但我在选择文本时遇到问题触摸。我在TextBox中双击以创建第一个“锚点”,然后拖动以开始选择;但我只能在选择停止之前正常选择一个字符。 TextBox不会完全失去焦点,但行为与此类似;选择锚会消失,除非我重新双击以开始新的选择,否则我无法继续选择任何内容。如果我删除代码以在TextBox2中选择文本,则Touch选择在TextBox1中表现完美。

我一直在尝试解决这一段时间,不能,我不知道如果我可以得到与WinRT文本框所需的行为。有没有人有任何想法?或者也许另一种方式来实现一个解决方案与这两个文本框的行为?

非常感谢。

回答

0

所以这远不是答案,但发现了一些可能会帮助你或其他人想出一个潜在的解决方法的东西。道歉,如果这些是你已经看到和注意到的事情。

首先,它不是TextBox2.Select()的调用本身就是问题。例如,这对我来说

private void txt1_SelectionChanged(object sender, RoutedEventArgs e) 
    { 
     var start = TextBox1.SelectionStart; 
     var length = TextBox1.SelectionLength; 
     TextBox2.Select(3, 5); 
    } 

遗憾的是做工精细,用startlength与硬编码的3和5,即,下面,不工作:

private void txt1_SelectionChanged(object sender, RoutedEventArgs e) 
    { 
     var start = TextBox1.SelectionStart; 
     var length = TextBox1.SelectionLength; 
     TextBox2.Select(start, length); 
    } 

我还发现如果我从最后开始,我可以选择两个字符,但从一开始只有一个字符。这让我想到调度呼叫设置第二选择:

private void txt1_SelectionChanged(object sender, RoutedEventArgs e) 
    { 
     var start = TextBox1.SelectionStart; 
     var length = TextBox1.SelectionLength; 
     Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Low, 
      () => TextBox2.Select(start, length)); 
    } 

现在我可以从前面选择2,从后面选择3,有时4。更进一步,并能够通过真正快速的滑动来选择多达六到七个。

private void txt1_SelectionChanged(object sender, RoutedEventArgs e) 
    { 
     var start = TextBox1.SelectionStart; 
     var length = TextBox1.SelectionLength; 
     Dispatcher.RunIdleAsync((v) => Highlight()); 
    } 

    public void Highlight() 
    { 
     TextBox2.Select(TextBox1.SelectionStart, TextBox1.SelectionLength); 
    } 

好像招解决这个工作是不是设置TextBox2中,直到无论TextBox1的SelectionChanged事件的痕迹已经完成。

这可能值得注册Connect

0

矿井也只是部分解决方案。

我做了一些调试,并注意到SelectionChanged事件在整个文本选择过程中被触发。换句话说,单个手指“滑动”将会生成多个SelectionChanged事件。

正如您发现的那样,在文本选择手势期间调用TextBox.Select会影响手势本身。 Windows似乎在程序化文本选择后停止了该手势。

我的解决方法是尽可能延迟调用TextBox.Select方法。除了一个边缘情况,这确实很好。如果这方法失败是在以下情形:

用户开始选择手势,说选择X字符。用户在不脱离屏幕的情况下,暂停一两秒钟。用户然后尝试选择更多的字符。

我的解决方案不处理上一段中的最后一位。暂停后的触摸选择实际上不会选择任何内容,因为我的代码将调用TextBox.Select方法。

这里是实际的代码。正如我上面提到的,在单个选择手势期间触发了多个选择更改事件。我的代码使用定时器计数器一起只有当不再有任何未决的触摸生成的选择改变的事件做了纲领性的选择。

int _selectCounter = 0; 
const int SELECT_TIMER_LENGTH = 500; 
async private void TextBox1_SelectionChanged(object sender, RoutedEventArgs e) 
{ 
    // _selectCounter is the number of selection changed events that have fired. 
    // If you are really paranoid, you will want to make sure that if 
    // _selectCounter reaches MAX_INT, that you reset it to zero. 
    int mySelectCount = ++_selectCounter; 

    // start the timer and wait for it to finish 
    await Task.Delay(SELECT_TIMER_LENGTH); 

    // If equal (mySelectCount == _selectCounter), 
    // this means that NO select change events have fired 
    // during the delay call above. We only do the 
    // programmatic selection when this is the case. 
    // Feel free to adjust SELECT_TIMER_LENGTH to suit your needs. 
    if (mySelectCount == _selectCounter) 
    { 
     this.TextBox2.Select(this.TextBox1.SelectionStart, this.TextBox1.SelectionLength); 
    } 
} 
相关问题