Я пишу программу WPF и пытаюсь найти способ форматирования данных в TextBox с помощью некоторого повторяемого метода, такого как стиль или шаблон. У меня много текстовых полей (точнее 95), и каждый из них привязан к своим числовым данным, для каждого из которых может быть определено собственное разрешение. Например, если данные 99,123 с разрешением 2, тогда должно отображаться 99,12. Точно так же значение данных 99 и разрешение 3 должны отображаться как 99,000 (а не 99). Есть ли способ сделать это?
Изменить: я должен уточнить, на текущем экране, над которым я работаю, 95 текстовых полей, но я хочу, чтобы каждое текстовое поле на разных экранах в моей программе отображало правильное количество десятичных знаков. Теперь, когда я думаю об этом, некоторые из них - это TextBoxes (например, экран, над которым я сейчас работаю), а некоторые - DataGrids или ListViews, но если я смогу выяснить, как заставить его работать для TextBoxes, я уверен, что смогу понять это также для других элементов управления.
В этом случае не так много кода, чтобы поделиться, но я постараюсь сделать его более понятным:
У меня есть модель представления, которая содержит следующие свойства (vb.net):
Public ReadOnly Property Resolution As Integer
Get
Return _signal.DisplayResolution
End Get
End Property
Public ReadOnly Property Value As Single
Get
Return Math.Round(_signal.DisplayValue, Resolution)
End Get
End Property
и в XAML у меня есть:
<UserControl.Resources>
<vm:SignalViewModel x:Key="Signal" SignalPath="SomeSignal"/>
</UserControl.Resources>
<TextBox Grid.Column="3" IsEnabled="False" Text="{Binding Path=Value, Source={StaticResource Signal}, Mode=OneWay}" />
РЕДАКТИРОВАТЬ2 (мое решение): Оказалось, что, отойдя на некоторое время от компьютера, я вернулся, чтобы найти простой ответ, который смотрел мне в лицо. Отформатируйте данные в модели представления!
Public ReadOnly Property Value As String
Get
Return (Strings.FormatNumber(Math.Round(_signal.DisplayValue, _signal.DisplayResolution), _signal.DisplayResolution))
End Get
End Property
источник
IValueConverter
? Передайте преобразователю фактическое значение и разрешение, и пусть он сам сделает округление за вас. Трудно предложить,StringFormat
не зная, как именноTextBox
генерируются эти 95 .Ответы:
Вы должны использовать
StringFormat
наBinding
. Вы можете использовать как стандартные строковые форматы , так и настраиваемые строковые форматы :<TextBox Text="{Binding Value, StringFormat=N2}" /> <TextBox Text="{Binding Value, StringFormat={}{0:#,#.00}}" />
Обратите внимание, что метод
StringFormat
работает только в том случае, если целевое свойство имеет строковый тип. Если вы пытаетесь установить что-то вродеContent
свойства (typeof(object)
), вам нужно будет использовать пользовательскийStringFormatConverter
( например, здесь ) и передать строку формата какConverterParameter
.Изменить для обновленного вопроса
Итак, если вы
ViewModel
определяете точность, я бы рекомендовал сделать это какMultiBinding
и создать свой собственныйIMultiValueConverter
. На практике это довольно раздражает, переходить от простой привязки к привязке, которую нужно расширить до aMultiBinding
, но если точность неизвестна во время компиляции, это почти все, что вы можете сделать. ВамIMultiValueConverter
нужно будет взять значение и точность и вывести отформатированную строку. Вы сможете сделать это, используяString.Format
.Однако для таких вещей, как a
ContentControl
, это гораздо проще сделать с помощьюStyle
:<Style TargetType="{x:Type ContentControl}"> <Setter Property="ContentStringFormat" Value="{Binding Resolution, StringFormat=N{0}}" /> </Style>
ContentStringFormat
Таким образом можно использовать любой элемент управления, который предоставляет объект . К сожалению,TextBox
ничего подобного нет.источник
#,#.00
, не компилируется - запятая интерпретируется как разделитель атрибутов вBinding
расширении разметки.StringFormat={}{0:#,#.00}
. Я обновлю ответ, чтобы он работал правильно.Принятый ответ не показывает 0 в целочисленном разряде при вводе типа 0,299. Он показывает .3 в пользовательском интерфейсе WPF. Итак, мое предложение использовать следующий строковый формат
<TextBox Text="{Binding Value, StringFormat={}{0:#,0.0}}"
источник
void NumericTextBoxInput(object sender, TextCompositionEventArgs e) { TextBox txt = (TextBox)sender; var regex = new Regex(@"^[0-9]*(?:\.[0-9]{0,1})?$"); string str = txt.Text + e.Text.ToString(); int cntPrc = 0; if (str.Contains('.')) { string[] tokens = str.Split('.'); if (tokens.Count() > 0) { string result = tokens[1]; char[] prc = result.ToCharArray(); cntPrc = prc.Count(); } } if (regex.IsMatch(e.Text) && !(e.Text == "." && ((TextBox)sender).Text.Contains(e.Text)) && (cntPrc < 3)) { e.Handled = false; } else { e.Handled = true; } }
источник