WPF (с C #) Проблема положения курсора TextBox

У меня есть программа WPF C #, в которой я пытаюсь удалить определенные символы из текстового поля в событии TextChanged. Скажем, например, знак доллара. Вот код, который я использую.

private void txtData_TextChanged(object sender, TextChangedEventArgs e)
{
      string data = txtData.Text;

      foreach( char c in txtData.Text.ToCharArray() )
      {
            if( c.ToString() == "$" )
            {
                  data = data.Replace( c.ToString(), "" );
            }
      }

      txtData.Text = data;
}

У меня проблема в том, что всякий раз, когда пользователь вводит знак $ (Shift + 4), в событии TextChanged он удаляет символ $ из текста текстового поля, но он также перемещает курсор в НАЧАЛО текстового поля, которое не является моим желаемая функциональность.

В качестве обходного пути я подумал о перемещении курсора в конец текста в текстовом поле, но проблема в том, что если бы курсор был расположен в некоторой средней позиции, это было бы не очень удобно для пользователя. Скажем, например, текст в текстовом поле был 123ABC, и если бы у меня был курсор после 3, то перемещение курсора в конец текста означало бы, что при следующем нажатии клавиши пользователь будет вводить данные после C, а не после 3, что является нормальный функционал.

Кто-нибудь знает, почему происходит это смещение курсора?


person Sach    schedule 31.08.2011    source источник
comment
Не связано, но знаете ли вы, что вы можете сделать: txtData.Text.Replace ($,), который заменит все вхождения $? Нет необходимости в этом цикле.   -  person ChrisWue    schedule 31.08.2011
comment
Вы также можете посмотреть событие PreviewTextInput.   -  person Paul Walls    schedule 31.08.2011
comment
Спасибо, Пол, да, я, наконец, закончил использовать PreviewTextInpu, где я избегаю всех ненужных символов.   -  person Sach    schedule 05.09.2011


Ответы (4)


Это не ответ на ваш вопрос, но, вероятно, решение вашей проблемы:

Как определить ограничения ввода TextBox?

Если это для вас излишне, установите e.Handled = true для всех символов, которых вы хотите избежать, в PreviewKeyDown (используйте Keyboard.Modifiers для клавиши SHIFT) или PreviewTextInput.

Попробуйте TextBox.CaretIndex для восстановления позиции курсора в TextChanged событии.

Надеюсь, поможет.

person LPL    schedule 01.09.2011
comment
Спасибо LPL, в итоге я использовал PreviewTextINput. - person Sach; 05.09.2011
comment
CaretIndex действительно был полезен. Ваше здоровье - person Alex; 03.06.2013

Вы можете использовать функцию Select TextBox, чтобы изменить положение курсора.

private void textBox1_TextChanged(object sender, TextChangedEventArgs e)
{
    textBox1.Text = textBox1.Text.Replace("$", "");            
    textBox1.Select(textBox1.Text.Length, 0);
}

Дополнительную информацию о положении курсора можно найти в MSDN

person Shebin    schedule 31.08.2011
comment
Сач предпочитает курсор на предыдущей позиции, а не в конце. - person LPL; 31.08.2011
comment
Согласитесь с LPL, я хочу имитировать точную функциональность, которую вы получаете, когда вводите текст в любое обычное текстовое поле. Только, если это $ (есть другие символы, которых я тоже хочу избежать), я не хочу, чтобы он отображался, И я хочу, чтобы курсор оставался на месте. - person Sach; 01.09.2011

Вы можете использовать свойство SelectionStart текстового поля. Возможно, что-то в этом роде должно сработать:

private void txtData_TextChanged(object sender, TextChangedEventArgs e)
{
  var pos = txtData.SelectionStart;
  string data = txtData.Text.Replace("$", "");
  txtData.Text = data;
  txtData.SelectionStart = pos;
}
person ChrisWue    schedule 31.08.2011
comment
Это тоже не работает. Он по какой-то причине перемещает курсор в следующую позицию после того, как я нажму Shift + $. - person Sach; 01.09.2011

Вы можете попробовать образец регулярного выражения

1) Используйте PreviewTextInput="CursorIssueHandler" в файле .xaml

2) В вашем файле .cs напишите следующий код:

    private void CursorIssueHandler(object sender, TextCompositionEventArgs e)
    {
        var TB = (sender as TextBox);
        Regex regex = new Regex("[^0-9a-zA-Z-]+");
        bool Valid = regex.IsMatch(e.Text);
        //System.Diagnostics.Debug.WriteLine(Valid); // check value for valid n assign e.Handled accordingly your requirement from regex
        e.Handled = Valid;
     }
person RisingDeveloper    schedule 19.09.2019