¿Cómo formatear el número de decimales en wpf usando estilo/plantilla?
Estoy escribiendo un programa WPF y estoy tratando de encontrar una manera de formatear los datos en un cuadro de texto a través de algún método repetible como un estilo o plantilla. Tengo muchos cuadros de texto (95 para ser exactos) y cada uno está vinculado a sus propios datos numéricos que pueden tener su propia resolución definida. Por ejemplo, si los datos son 99.123 con una resolución de 2, entonces debería mostrar 99.12. Del mismo modo, un valor de datos de 99 y la resolución 3 deben mostrarse como 99.000 (no 99). ¿Hay una manera de hacer ¿esto?
Editar: Debo aclarar, hay 95 cuadros de texto en la pantalla actual en la que estoy trabajando, pero quiero que cada cuadro de texto en las diversas pantallas de mi programa muestre el número correcto de decimales. Ahora que lo pienso, algunos de estos son cuadros de texto (como la pantalla en la que estoy trabajando ahora) y algunos son DataGrids o ListViews, pero si puedo averiguar cómo hacerlo funcionar para cuadros de texto Estoy seguro de que puedo averiguarlo para los otros controles como bien.
No hay mucho código para compartir en este caso, pero intentaré hacerlo más claro:
Tengo un Modelo de vista que contiene las siguientes propiedades (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
Y en el XAML tengo:
<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 (mi solución): Resulta que después de alejarme de la computadora por un tiempo, volví para encontrar una respuesta simple que me estaba mirando a la cara. Formatee los datos en el modelo de vista!
Public ReadOnly Property Value As String
Get
Return (Strings.FormatNumber(Math.Round(_signal.DisplayValue, _signal.DisplayResolution), _signal.DisplayResolution))
End Get
End Property
3 answers
Debe usar el StringFormat
en el Binding
. Puedes usar formatos de cadena estándar , o formatos de cadena personalizados :
<TextBox Text="{Binding Value, StringFormat=N2}" />
<TextBox Text="{Binding Value, StringFormat={}{0:#,#.00}}" />
Tenga en cuenta que StringFormat
solo funciona cuando la propiedad de destino es de tipo string. Si está intentando establecer algo como una propiedad Content
(typeof(object)
), necesitará usar una propiedad personalizada StringFormatConverter
(como aquí ), y pase su cadena de formato como ConverterParameter
.
Editar para la pregunta actualizada
Por lo tanto, si su ViewModel
define la precisión, yo recomendaría hacer esto como un MultiBinding
, y crear su propio IMultiValueConverter
. Esto es bastante molesto en la práctica, pasar de un simple enlace a uno que necesita expandirse a MultiBinding
, pero si la precisión no se conoce en tiempo de compilación, esto es prácticamente todo lo que puede hacer. Su IMultiValueConverter
tendría que tomar el valor, y la precisión, y la salida de la cadena formateada. Usted podría hacer esto usando String.Format
.
Sin embargo, para cosas como un ContentControl
, puede hacer esto mucho más fácilmente con a Style
:
<Style TargetType="{x:Type ContentControl}">
<Setter Property="ContentStringFormat"
Value="{Binding Resolution, StringFormat=N{0}}" />
</Style>
Cualquier control que exponga un ContentStringFormat
puede ser usado así. Desafortunadamente, TextBox
no tiene nada como eso.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-04 18:06:21
La respuesta aceptada no muestra 0 en el lugar entero al dar entrada como 0.299. Se nota .3 en la interfaz de usuario de WPF. Así que mi sugerencia de utilizar el siguiente formato de cadena
<TextBox Text="{Binding Value, StringFormat={}{0:#,0.0}}"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-04 09:37:23
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;
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-05 11:55:43