Я пытаюсь отобразить отформатированное десятичное число в TextBox, используя привязку данных в WPF.
Цели
Цель 1: при установке десятичного значения в коде отобразите 2 десятичных знака в текстовом поле.
Цель 2: Когда пользователь взаимодействует с (вводит) в TextBox, не срывает его/ее.
Цель 3: привязки должны обновлять источник в PropertyChanged.
Попытки
Попытка 1: Без форматирования.
Здесь мы начинаем почти с нуля.
<TextBox Text="{Binding Path=SomeDecimal, UpdateSourceTrigger=PropertyChanged}" />
Нарушает цель 1. SomeDecimal = 4.5
отобразит "4.50000" в текстовом поле.
Попытка 2: Использовать StringFormat в привязке.
<TextBox Text="{Binding Path=SomeDecimal, UpdateSourceTrigger=PropertyChanged, StringFormat=F2}" />
Нарушает цель 2. Скажите SomeDecimal значение 2.5, а TextBox отображает "2.50". Если мы выберем все и наберем "13.5", мы получим "13.5.00" в TextBox, потому что форматирование "полезно" вставляет десятичные знаки и нули.
Попытка 3: использовать расширенный набор инструментов WPF MaskedTextBox.
http://wpftoolkit.codeplex.com/wikipage?title=MaskedTextBox
Предполагая, что я правильно читаю документацию, маска ## 0.00 означает "две необязательные цифры, за которой следует требуемая цифра, десятичная точка и еще две требуемые цифры". Это заставляет меня сказать "максимально возможное число, может войти в этот TextBox 999.99", но пусть говорят, что я в порядке с этим.
<xctk:MaskedTextBox Value="{Binding Path=SomeDecimal, UpdateSourceTrigger=PropertyChanged}" Mask="##0.00" />
Нарушает цель 2. TextBox начинается с ___.__
и выбирает его и набирает 5.75 уроков 575.__
. Единственный способ получить 5.75 - выбрать TextBox и набрать <space><space>5.75
.
Попытка 4: использовать расширенный WPF Toolkit DecimalUpDown spinner.
http://wpftoolkit.codeplex.com/wikipage?title=DecimalUpDown
<xctk:DecimalUpDown Value="{Binding Path=SomeDecimal, UpdateSourceTrigger=PropertyChanged}" FormatString="F2" />
Нарушает цель 3. DecimalUpDown с радостью игнорирует UpdateSourceTrigger = PropertyChanged. Один из координаторов на странице расширенного WPF Toolkit Codeplex предлагает модифицированный контрольный шаблон в http://wpftoolkit.codeplex.com/discussions/352551/. Это удовлетворяет цели 3, но нарушает цель 2, проявляя то же поведение, что и в попытке 2.
Попытка 5: использование стилей datatriggers, используйте только форматирование, если пользователь не редактирует.
Связывание с двойным с StringFormat в TextBox
Даже если бы этот был удовлетворен всем трем целям, я бы не хотел его использовать. (A) Текстовые поля становятся 12 строк каждый вместо 1, а мое приложение содержит много и много текстовых полей. (B) Все мои текстовые поля уже имеют атрибут Style, который указывает на глобальный StaticResource, который устанавливает Margin, Height и другие вещи. (C) Возможно, вы заметили, что приведенный ниже код устанавливает путь привязки дважды, что нарушает принципал DRY.
<TextBox>
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Text" Value="{Binding Path=SomeDecimal, StringFormat=F2}" />
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Text" Value="{Binding Path=SomeDecimal, UpdateSourceTrigger=PropertyChanged}" />
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
Все эти неудобные вещи в стороне...
Нарушает цель 2. Сначала щелчок на TextBox, который отображает "13.50", внезапно отображает "13.5000", что неожиданно. Во-вторых, если начать с пустого TextBox, и я набираю "13.50", TextBox будет содержать "1350". Я не могу объяснить, почему, но нажатие клавиши периода не вставляет десятичные знаки, если курсор находится в правом конце строки в TextBox. Если TextBox содержит строку с длиной > 0, и я перемещаю курсор в любую точку, кроме правого конца строки, тогда я могу вставить десятичные точки.
Попытка 6: сделайте это сама.
Я собираюсь приступить к jouney боли и страдания, либо подклассифицируя TextBox, либо создав прикрепленное свойство, и сам написав код форматирования. Он будет наполнен струнными манипуляциями и вызовет существенную потерю волос.
Есть ли у кого-нибудь предложения по форматированию десятичных знаков, привязанных к текстовым полям, которые удовлетворяют всем вышеперечисленным целям?