J'écris un programme WPF et j'essaie de trouver un moyen de formater des données dans une zone de texte à l'aide d'une méthode répétable telle qu'un style ou un modèle. J'ai beaucoup de TextBoxes (95 pour être exact) et chacun est lié à ses propres données numériques qui peuvent chacune avoir leur propre résolution définie. Par exemple, si les données sont 99.123 avec une résolution de 2, elles doivent afficher 99.12. De même, une valeur de données de 99 et la résolution 3 doivent être affichées sous la forme 99 000 (et non 99). Y a-t-il un moyen de faire cela?
Edit: Je devrais préciser, il y a 95 zones de texte sur l’écran actuel sur lequel je travaille, mais je veux que chaque zone de texte située sur les différents écrans de mon programme affiche le nombre correct de décimales. Maintenant que j'y pense, il y a des TextBox (comme l'écran sur lequel je travaille maintenant) et des DataGrids ou ListViews, mais si je peux trouver comment faire pour que ça fonctionne avec les TextBox, je suis sûr de pouvoir comprendre pour les autres contrôles aussi.
Il n'y a pas beaucoup de code à partager dans ce cas, mais je vais essayer de le rendre plus clair:
J'ai un modèle de vue qui contient les propriétés suivantes (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
et dans le XAML j'ai:
<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 (ma solution): Il s'est avéré qu'après m'être éloignée de l'ordinateur pendant un moment, je suis revenue pour trouver une réponse simple qui me fixait au visage. Formatez les données dans le modèle de vue!
Public ReadOnly Property Value As String
Get
Return (Strings.FormatNumber(Math.Round(_signal.DisplayValue, _signal.DisplayResolution), _signal.DisplayResolution))
End Get
End Property
Vous devez utiliser le StringFormat
sur le Binding
. Vous pouvez utiliser soit formats de chaîne standard , ou formats de chaîne personnalisés :
<TextBox Text="{Binding Value, StringFormat=N2}" />
<TextBox Text="{Binding Value, StringFormat={}{0:#,#.00}}" />
Notez que StringFormat
ne fonctionne que lorsque la propriété target est de type chaîne. Si vous essayez de définir quelque chose comme une propriété Content
(typeof(object)
), vous devrez utiliser un paramètre personnalisé StringFormatConverter
( comme ici ) et transmettre votre chaîne de format comme le ConverterParameter
.
Modifier pour la question mise à jour
Donc, si votre ViewModel
définit la précision, je vous recommande de le faire en tant que MultiBinding
et de créer votre propre IMultiValueConverter
. En pratique, c’est assez ennuyant de passer d’une simple liaison à une autre qui doit être étendue à un MultiBinding
, mais si la précision n’est pas connue au moment de la compilation, c’est quasiment tout ce que vous pouvez faire. Votre IMultiValueConverter
devra prendre la valeur, la précision et la chaîne formatée. Vous pourrez le faire en utilisant String.Format
.
Cependant, pour des choses comme un ContentControl
, vous pouvez le faire beaucoup plus facilement avec un Style
:
<Style TargetType="{x:Type ContentControl}">
<Setter Property="ContentStringFormat"
Value="{Binding Resolution, StringFormat=N{0}}" />
</Style>
Tout contrôle qui expose une ContentStringFormat
peut être utilisé comme ceci. Malheureusement, TextBox
n'a rien de tel.
La réponse acceptée n’indique pas 0 à la place d’un nombre entier en donnant une entrée comme 0.299. Il montre .3 dans l'interface utilisateur WPF. Donc, ma suggestion d'utiliser le format de chaîne suivant
<TextBox Text="{Binding Value, StringFormat={}{0:#,0.0}}"