Замена клавиши десятичной точки (с цифровой клавиатуры) на правильный десятичный разделитель (в silverlight!)

Что я пытаюсь сделать, когда пользователь находится в текстовом поле (в silverlight 2.0):

  • Когда пользователь нажимает десятичную точку (.) на цифровой клавиатуре, я хочу, чтобы она была заменена правильным десятичным разделителем (во многих странах это запятая (,))

Я могу отследить, что пользователь ввел десятичную точку, проверив событие нажатия клавиши

void Cell_KeyDown(object sender, KeyEventArgs e)
{
     if (e.Key == Key.Decimal)

Но как мне заменить этот ключ другим в Silverlight? e.Key доступен только для чтения. Есть ли способ «послать другой ключ» элементу управления? Или любые другие предложения?


person Tjipke    schedule 04.12.2008    source источник


Ответы (8)


Ответ был найден на веб-сайте MSDN: Replace-numpad-decimalpoint

Imports System.Threading
Imports System.Windows.Forms

Namespace My


    ' The following events are available for MyApplication:
    ' 
    ' Startup: Raised when the application starts, before the startup form is created.
    ' Shutdown: Raised after all application forms are closed.  This event is not raised if the application terminates abnormally.
    ' UnhandledException: Raised if the application encounters an unhandled exception.
    ' StartupNextInstance: Raised when launching a single-instance application and the application is already active. 
    ' NetworkAvailabilityChanged: Raised when the network connection is connected or disconnected.

    Partial Friend Class MyApplication
        Private Sub MyApplication_Startup(ByVal sender As Object, ByVal e As Microsoft.VisualBasic.ApplicationServices.StartupEventArgs) Handles Me.Startup
            If Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator <> "." Then
                System.Windows.Forms.Application.AddMessageFilter(New CommaMessageFilter)

            End If
        End Sub

    End Class

    Friend Class CommaMessageFilter
        Implements IMessageFilter
        Private Const WM_KEYDOWN = &H100

        Public Function PreFilterMessage(ByRef m As System.Windows.Forms.Message) As Boolean Implements IMessageFilter.PreFilterMessage

            If m.Msg = WM_KEYDOWN Then
                Dim toets As Keys = CType(CType(m.WParam.ToInt32 And Keys.KeyCode, Integer), Keys)
                If toets = Keys.Decimal Then
                    SendKeys.Send(Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator)
                    Return True
                End If
            End If
            Return False
        End Function
    End Class

End Namespace
person Pete    schedule 23.04.2012
comment
Спасибо, это было идеальное решение. - person Bjorn; 18.11.2016

public class NumericUpDown : System.Windows.Controls.NumericUpDown
{
    [DebuggerStepThrough]
    protected override double ParseValue(string text)
    {
        text = text.Replace(".", Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator);
        return base.ParseValue(text);
    }
}

Ваше здоровье

person TheOnlyMaX    schedule 31.08.2011

У меня есть решение, которое я использую в своих приложениях winforms, предполагается, что оно также должно работать в silverlight. Он в vb, но преобразовать его в C # не должно быть проблемой. Посмотрите здесь: http://code.msdn.microsoft.com/Replace-numpad-decimalpoint-c1e0e6cd

person nico boey    schedule 20.04.2012

Вы можете вносить изменения в _LostFocus, заменяя точку на запятую или применяя правильную культуру для ввода.

Он не внесет изменения сразу, как вы хотите, но сделает это, как только пользователь выйдет из текстового поля.

person NikolaiDante    schedule 04.12.2008
comment
Спасибо за предложение, но из пользовательского pov это не очень ясно: он видит 1.5, пока он не выйдет из tb, а затем он станет 1,5 ... - person Tjipke; 04.12.2008

Вероятно, вы могли бы прочитать событие «нажатие клавиши» вместо «нажатие клавиши» и заменить все содержимое текстового поля своей (всей) предпочтительной заменяемой строкой при каждом нажатии клавиши.

Однако я думаю, что вы идете неверным путем. На клавиатуре есть клавиша ','. Я бы предположил, что если бы ваш пользователь хотел ввести "," потому что это стандарт в его стране, то это то, что он сделал бы. Замена клавиш на экране просто сбивает с толку.

person Alterlife    schedule 04.12.2008
comment
Спасибо за ваше первое предложение ... Я посмотрю, что я могу там сделать. Но это не сбивает с толку пользователей, для быстрого набора чисел они ожидают использования цифровой клавиатуры '.' как местный десятичный разделитель. Это то же самое, например, что делает Excel! Поэтому для ясности я говорю только о. на цифровой клавиатуре - person Tjipke; 04.12.2008

Используя ответ Alterlife в качестве подсказки для замены содержимого, у меня есть следующий рабочий хак ... Но мне он не нравится :-(.

  • Это означает, что свойство Text устанавливается дважды, один раз на неправильное значение, а затем заменяется на правильное значение.
  • Работает только для текстовых полей
  • Такое чувство, что однажды взлом может просто перестать работать

Поэтому приветствуются предложения по лучшим, более общим решениям!

Взлом:

    void CellText_KeyUp(object sender, KeyEventArgs e)
    {
        var DecSep = System.Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator;

        if (e.Key == Key.Decimal && DecSep != ".")
        {
            if (e.OriginalSource is TextBox)
            {
                var TB = (TextBox)e.OriginalSource;
                string sText = TB.Text;

                int iPos = TB.SelectionStart - 1;
                if (iPos >= 0)
                {
                    System.Diagnostics.Debug.Assert(sText.Substring(iPos, 1) == ".");

                    TB.Text = sText.Substring(0, iPos) + DecSep + sText.Substring(iPos + 1);
                    TB.SelectionStart = iPos + 1; // reposition cursor
                }
            }
        }
    }
person Tjipke    schedule 04.12.2008

Вы пытаетесь переопределить настройки локали вашей системы, что может сбить с толку ваших пользователей, когда они получают неправильный ответ от введенного ими ключа ... Что вы можете сделать, так это написать преобразователь значений, который обеспечит правильное отображение значения формируется перед записью в связанное поле данных. Предполагая, что ваше текстовое поле привязано к базовому полю данных ...

person AndrejT    schedule 07.12.2008
comment
Спасибо за ваш ответ, но нет, я не пытаюсь переопределить настройку языкового стандарта системы (по крайней мере, я так не думаю). Я пытаюсь использовать десятичную точку на цифровой клавиатуре в качестве DecimalSeparator. Этого и ожидают большинство пользователей (ввод данных). - person Tjipke; 11.12.2008

Это работает:

<html>
<heaD>
<script language="javascript">
function keypress1 ()
{
 var e=window.event || e
 unicode = e.charCode ? e.charCode : e.keyCode; 
 if (unicode==46)
   { return (e.charCode ? e.charCode=44 : e.keyCode=44); }
}
function keypress2 ()
{
 var e=window.event || e
 unicode = e.charCode ? e.charCode : e.keyCode; 
 if (unicode==46)
   { return (e.charCode ? e.charCode=46 : e.keyCode=46); }
}
function keyDown(e){
 if (!e){
   e = event
 }
 var code=e.keyCode;
 if(code==110)
   return document.onkeypress=keypress1
 else if(code=188)
   {  document.onkeypress=keypress2 }
}
document.onkeydown = keyDown
</script>
</head>
<body>
<input type=text>
</body>
</html>
person Savvy    schedule 13.11.2009