2013-04-10 75 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); 
    } 
} 
相關問題