Как отформатировать количество десятичных знаков в wpf с помощью стиля / шаблона?



Я пишу программу WPF, и я пытаюсь выяснить способ форматирования данных в текстовом поле с помощью некоторого повторяющегося метода, такого как стиль или шаблон. У меня есть много текстовых полей (95, если быть точным), и каждый из них привязан к своим собственным числовым данным, которые могут иметь свое собственное разрешение. Например, если данные 99.123 с разрешением 2, то он должен отображать 99.12. Аналогично значение данных 99 и разрешение 3 должны отображаться как 99.000 (не 99). Есть ли способ сделать это?



Edit:
Я должен уточнить, что на текущем экране, над которым я работаю, есть 95 текстовых полей, но я хочу, чтобы каждое текстовое поле на разных экранах в моей программе отображало правильное количество десятичных знаков. Теперь, когда я думаю об этом, некоторые из них являются текстовыми полями (например, экран, над которым я сейчас работаю), а некоторые-это DataGrids или ListViews, но если я могу понять, как заставить его работать для текстовых полей, я уверен, что смогу понять это для других элементов управления как что ж.



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



у меня есть модель представления, которая содержит следующие свойства (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}" />


EDIT2 (мое решение):
Оказывается, отойдя от компьютера на некоторое время, я вернулся, чтобы найти простой ответ, который смотрел мне в лицо. Отформатируйте данные в модели представления!



    Public ReadOnly Property Value As String
Get
Return (Strings.FormatNumber(Math.Round(_signal.DisplayValue, _signal.DisplayResolution), _signal.DisplayResolution))
End Get
End Property
798   3  

3 ответов:

вы должны использовать StringFormat на Binding. Вы можете использовать либо стандартные форматы строк или пользовательские форматы строк:

<TextBox Text="{Binding Value, StringFormat=N2}" />
<TextBox Text="{Binding Value, StringFormat={}{0:#,#.00}}" />

отметим, что StringFormat работает только тогда, когда целевое свойство имеет тип String. Если вы пытаетесь установить что-то вроде Content собственность (typeof(object)), вам нужно будет использовать пользовательский StringFormatConverter (как тут), и передать строку формата как ConverterParameter.

"редактировать" обновленный вопрос

поэтому, если ваш ViewModel определяет точность, я бы рекомендовал делать это как MultiBinding, и создание собственного IMultiValueConverter. Это довольно раздражает на практике, чтобы перейти от простой привязки к той, которая должна быть расширена до MultiBinding, но если точность не известна во время компиляции, это почти все, что вы можете сделать. Ваш IMultiValueConverter нужно будет взять значение и точность, а также вывести форматированную строку. Вы могли бы сделать это через String.Format.

Впрочем, для таких вещей, как ContentControl, вы можете гораздо легче сделать это с помощью Style:

<Style TargetType="{x:Type ContentControl}">
    <Setter Property="ContentStringFormat" 
            Value="{Binding Resolution, StringFormat=N{0}}" />
</Style>

любой элемент управления, который предоставляет ContentStringFormat можно использовать вот так. К сожалению, TextBox нет ничего подобного.

принятый ответ не показывает 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;
        }
    }

Comments

    Ничего не найдено.