TextBox с автоматическим форматированием культуры? - PullRequest
0 голосов
/ 05 декабря 2009

Я пытаюсь создать TextBox, который допускает только положительный целочисленный ввод, и который должен автоматически отображать ввод с учетом специфики культуры (в данном случае en-US, поэтому в качестве разделителя следует использовать знак ',' для больших чисел). Итак:

  • Запись 1000 должна отображаться как «1000» в TextBox
  • Запись 1000 должна отображаться как таковая, но должна интерпретироваться правильно ...

В настоящее время такое автоматическое форматирование не выполняется в первом случае, а во втором случае выдается ошибка из реализованного мною ValidationRule для проверки правильности ввода (который использует TryParse для проверки правильности числа). вошел).

Я смущаюсь новым мышлением здесь с точки зрения глобализации и интернационализации, поэтому мне интересно, есть ли какая-то магия, связанная с культурой сома, я могу работать, чтобы отделить отображаемое форматирование от фактических данных и сделать автоматизированное форматирование, во время ввода?

Это xaml для TextBox из кода:

<TextBox 
                Foreground="{StaticResource WindowForegroundBrush}" 
                Background="{StaticResource EntryFieldBackgroundBrush}" 
                TextWrapping="NoWrap" 
                MaxLines="1" 
                MaxLength="100" 
                Margin="{StaticResource EntryFormTextBoxMargins}" 
                VerticalAlignment="Stretch" 
                RenderTransformOrigin="0.5,0.5" 
                HorizontalAlignment="Stretch" 
                VerticalContentAlignment="Center" 
                MinWidth="300" 
                MinHeight="30" 
                x:Name="PopTxtBox" 
                MaxWidth="300" 
                TextChanged="PopTxtChange">
                <Binding 
                    Path="locationPopulation"                                                 
                    Source="{StaticResource locDT}" 
                    UpdateSourceTrigger="PropertyChanged">
                    <Binding.ValidationRules>
                        <c:PopValidationRule />
                    </Binding.ValidationRules>
                </Binding>

И вот Правило валидации, которое я написал:

   public class PopulationValidationRule : ValidationRule
    {
        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
        {
            UInt64 popValue;

            if (value == null)
            {
                return new ValidationResult(true, null);
            }
            else if (!UInt64.TryParse((string)value, NumberStyles.AllowThousands, null, out popValue))
            {
                return new ValidationResult(false, "Value must be a valid number.");
            }

            return new ValidationResult(true, null);
        }
    }

Кроме того, я бы хотел, чтобы TextBox мог отображаться как пустой - прямо сейчас TextBox отображает '0' при загрузке, а оставление TextBox пустым вызывает ошибку проверки (даже если я разрешаю это в Правило проверки). Насколько я могу понять, когда я связываю TextBox с числовым значением, ему не разрешается нулевое значение. Есть ли способ справиться с этим?

Ответы [ 2 ]

0 голосов
/ 08 декабря 2009

Ну, я получил это к моему удовольствию.

  • Видимо, мне пришлось указать, что привязка применяется конкретно к элементу TextBox.Text (почему я не сделал этого с самого начала, я не уверен). После этого StringFormat работал как рекламируется.

  • Я добавил довольно упрощенный обработчик события PreviewLostKeyboardFocus-event, который удаляет разделители групп, поскольку искомое значение должно быть неотформатированным ulong - затем форматирование экрана применяется нашим Преобразователь StringFormat, таким образом, ожидаемое значение уже не должно иметь такого форматирования (и, если оно имеет место, не проходит валидацию). Событие также удаляет любые потенциальные ведущие нули для хорошей меры.

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

Спасибо, ребята, за комментарии и идеи!

Код для моего TextBox:

 <TextBox 
                Foreground="{StaticResource WindowForegroundBrush}" 
                Background="{StaticResource EntryFieldBackgroundBrush}" 
                TextWrapping="NoWrap" 
                MaxLines="1" 
                MaxLength="100" 
                Margin="{StaticResource EntryFormTextBoxMargins}" 
                VerticalAlignment="Stretch" 
                RenderTransformOrigin="0.5,0.5" 
                HorizontalAlignment="Stretch" 
                VerticalContentAlignment="Center" 
                MinWidth="300" 
                MinHeight="30" 
                x:Name="PopTxtBox" 
                MaxWidth="300" PreviewLostKeyboardFocus="PopTxtBoxLeavePreview"                                         
                >
                <TextBox.Text>
                    <Binding 
                        Path="locationPopulation"                                                 
                        Source="{StaticResource locDT}"                        
                        UpdateSourceTrigger="LostFocus"
                        StringFormat="{}{0:#,#;;}">
                        <Binding.ValidationRules>
                            <dataTemplates:PopValidationRule />
                        </Binding.ValidationRules>
                    </Binding>
                </TextBox.Text>

            </TextBox>

Правило валидации:

public class PopValidationRule : ValidationRule
    {
        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
        {
            ulong popVal;

            if (!ulong.TryParse((string)value, out popVal) && !(value == null))
            {
                return new ValidationResult(false, "ValidationResult: Not a number.");
            }

            return new ValidationResult(true, null);
        }
    }

Событие PreviewLostKeyboard:

private void PopTxtBoxLeavePreview(object sender, System.Windows.Input.KeyboardFocusChangedEventArgs e)
    {
        TextBox senderBox = (TextBox)sender;

        //remove leading 0:s.
        senderBox.Text = senderBox.Text.TrimStart('0');
        //remove spaces as group separator
        senderBox.Text = senderBox.Text.Replace(" ", "");
        //remove commas as group separator
        senderBox.Text = senderBox.Text.Replace(",", "");
        //remove singlequotes as group separator
        senderBox.Text = senderBox.Text.Replace("'", "");            
    }
}
0 голосов
/ 05 декабря 2009

Вы можете найти это полезным, обращая внимание на класс CultureInfo

Эта статья содержит хорошее объяснение ..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...