none
StringFormat a un TExbox de WPF con formato númerico RRS feed

  • Pregunta

  • Buenas tardes, he tratado de hecer que un simple TexBox de WPF me contenga un formato numerico convencional por ejemplo 5.000,00 y se me ha convertido en una labor ardua por que nada de lo que he leido en foros y paginas me ha servido, se que es mas por desconocimiento y espero me ayuden con este caso que debe ser una cosa muy sencilla me imagino.

    La situación es la siguiente: Tengo una ventana de wpf donde tengo unos texbox los cuales lleno con los datos que selecciono de un datagrid que a su vez es cargado desde un List, para hacerlo hago algo como MiTExtBox.TExt = Valor.ToString(format: "#,#.00"), esto me muestra inicialmente el campo en el formato que quiero pero cuando escribo un nuevo valor en ese campo se desacomoda el formato, si escribo 5000 me lo deja tal cual sin los decimales ni los separadores de mil.

    Por otro lado en mi XAML uso algo como:

    Text = "{Binding Path=MiValor, StringFormat = \{0:N}\}

    No se que estaré haciendo mal o que me falta para poder tener mi campo en formato numerico, si alguen puede darme un ejemplo sencillo de como se hace lo agradecería mucho, Gracias amigos.


    C. Zapata

    miércoles, 14 de marzo de 2012 17:24

Respuestas

  • Hola Caza.

    Si, depende de el valor que quieras insertar debes hacer una cosa u otra. En el framework, el formato de cadenas solo es valido para el tipo especificado, por ejemplo solo puedes formatear una cadena de fecha si el origen es una fecha, y del mismo modo solo puedes formatear un numero en cadena si el origen es un numero, de modo que en tu ejemplo MiValor debe ser un valor numerico (por ejemplo int), para que el formato 0:N se aplique correctamente.

    No se como estas implementando la propiedad, pero siguiendo el modelo de programacion en WPF/Silverlight y haciendo uso de un ViewModel, este puede ser un ejemplo para que te sirva de guia.

    En el codigo del viewmodel una propiedad con el numero a enlazar al textbox (y la notificacion de la propiedad):

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Text;
    
    
    namespace WpfApplication7
    {
        class modelview : INotifyPropertyChanged
        {
            #region [Variables miembro]
    
            /// <summary>Variable para guardar el numero en una cadena</summary>
            private int m_textNumber;
    
            #endregion [Variables miembro]
    
            #region [propiedades]
    
            /// <summary>propiedad para establecer/obtener un numero</summary>
            public int TextNumber
            {
                get
                {
                    return m_textNumber;
                }
                set 
                {
                    // guardar el valor y notificar el cambio
                    this.m_textNumber = value;
                    this.OnPropertyChanged("TextNumber");
                }
            }
    
            #endregion [propiedades]
    
    
            #region [INotifyPropertyChanged]
    
            /// <summary>
            /// declarar el evento ocurrido cuando una propiedad de este objeto tiene un nuevo valor
            /// </summary>
            public event PropertyChangedEventHandler PropertyChanged;
    
            /// <summary>
            /// Definicion del evento PropertyChanged que sera llamado cuando un valor de una propiedad sea modificado
            /// </summary>
            /// <param name="_propertyName">El nombre de la propiedad con el nuevo valor</param>
            protected virtual void OnPropertyChanged(string _propertyName)
            {
                // añadir el manejador del evento
                PropertyChangedEventHandler handler = PropertyChanged;
                // si existe el manejador del evento, se invoca
                if (handler != null) handler(this, new PropertyChangedEventArgs(_propertyName));
            }
    
            #endregion [INotifyPropertyChanged]
        }
    }
    

    esta es una clase para simular un viewmodel con una propiedad que hace de numero a enlazar.

    En el codigo xaml tan solo el textbox enlazado y formateado:

    <Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:WpfApplication7"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
            mc:Ignorable="d" 
            x:Class="WpfApplication7.MainWindow"
            Title="MainWindow" Height="350" Width="525">
        
    	<Window.Resources>
    		<local:modelview x:Key="modelviewDataSource" d:IsDataSource="True"/>
    	</Window.Resources>
        
        <Grid DataContext="{Binding Source={StaticResource modelviewDataSource}}">
            
            <TextBox Height="23" HorizontalAlignment="Left" Margin="50,168,0,0" x:Name="textBox1" VerticalAlignment="Top" Width="120" 
                     Text="{Binding UpdateSourceTrigger=PropertyChanged, Path=TextNumber, StringFormat=\{0:N\}}" />
        </Grid>
    </Window>

    Y con esto veras como al modificar la propiedad del viewmodel se vera afectada la presentacion del numero, por supuesto como el enlace es bidireccional cuando modifiques el textbox se modificara la propiedad y se formateara automaticamente, ya que esta establecido el trigger para el cambio de propiedad en el binding.

    pruebalo y me comentas.


    Saludos
    David González
    MCP, MCTS
    Visita mi Blog en: http://www.dgzornoza.com/

    • Propuesto como respuesta CorsarioVasco jueves, 15 de marzo de 2012 8:29
    • Marcado como respuesta CAZA - viernes, 16 de marzo de 2012 2:18
    miércoles, 14 de marzo de 2012 21:34

Todas las respuestas

  • Hola Caza.

    Si, depende de el valor que quieras insertar debes hacer una cosa u otra. En el framework, el formato de cadenas solo es valido para el tipo especificado, por ejemplo solo puedes formatear una cadena de fecha si el origen es una fecha, y del mismo modo solo puedes formatear un numero en cadena si el origen es un numero, de modo que en tu ejemplo MiValor debe ser un valor numerico (por ejemplo int), para que el formato 0:N se aplique correctamente.

    No se como estas implementando la propiedad, pero siguiendo el modelo de programacion en WPF/Silverlight y haciendo uso de un ViewModel, este puede ser un ejemplo para que te sirva de guia.

    En el codigo del viewmodel una propiedad con el numero a enlazar al textbox (y la notificacion de la propiedad):

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Text;
    
    
    namespace WpfApplication7
    {
        class modelview : INotifyPropertyChanged
        {
            #region [Variables miembro]
    
            /// <summary>Variable para guardar el numero en una cadena</summary>
            private int m_textNumber;
    
            #endregion [Variables miembro]
    
            #region [propiedades]
    
            /// <summary>propiedad para establecer/obtener un numero</summary>
            public int TextNumber
            {
                get
                {
                    return m_textNumber;
                }
                set 
                {
                    // guardar el valor y notificar el cambio
                    this.m_textNumber = value;
                    this.OnPropertyChanged("TextNumber");
                }
            }
    
            #endregion [propiedades]
    
    
            #region [INotifyPropertyChanged]
    
            /// <summary>
            /// declarar el evento ocurrido cuando una propiedad de este objeto tiene un nuevo valor
            /// </summary>
            public event PropertyChangedEventHandler PropertyChanged;
    
            /// <summary>
            /// Definicion del evento PropertyChanged que sera llamado cuando un valor de una propiedad sea modificado
            /// </summary>
            /// <param name="_propertyName">El nombre de la propiedad con el nuevo valor</param>
            protected virtual void OnPropertyChanged(string _propertyName)
            {
                // añadir el manejador del evento
                PropertyChangedEventHandler handler = PropertyChanged;
                // si existe el manejador del evento, se invoca
                if (handler != null) handler(this, new PropertyChangedEventArgs(_propertyName));
            }
    
            #endregion [INotifyPropertyChanged]
        }
    }
    

    esta es una clase para simular un viewmodel con una propiedad que hace de numero a enlazar.

    En el codigo xaml tan solo el textbox enlazado y formateado:

    <Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:WpfApplication7"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
            mc:Ignorable="d" 
            x:Class="WpfApplication7.MainWindow"
            Title="MainWindow" Height="350" Width="525">
        
    	<Window.Resources>
    		<local:modelview x:Key="modelviewDataSource" d:IsDataSource="True"/>
    	</Window.Resources>
        
        <Grid DataContext="{Binding Source={StaticResource modelviewDataSource}}">
            
            <TextBox Height="23" HorizontalAlignment="Left" Margin="50,168,0,0" x:Name="textBox1" VerticalAlignment="Top" Width="120" 
                     Text="{Binding UpdateSourceTrigger=PropertyChanged, Path=TextNumber, StringFormat=\{0:N\}}" />
        </Grid>
    </Window>

    Y con esto veras como al modificar la propiedad del viewmodel se vera afectada la presentacion del numero, por supuesto como el enlace es bidireccional cuando modifiques el textbox se modificara la propiedad y se formateara automaticamente, ya que esta establecido el trigger para el cambio de propiedad en el binding.

    pruebalo y me comentas.


    Saludos
    David González
    MCP, MCTS
    Visita mi Blog en: http://www.dgzornoza.com/

    • Propuesto como respuesta CorsarioVasco jueves, 15 de marzo de 2012 8:29
    • Marcado como respuesta CAZA - viernes, 16 de marzo de 2012 2:18
    miércoles, 14 de marzo de 2012 21:34
  • Hola antes que nada pienso que este foro esta un valor humano importante del cual formas parte. Tu respuesta la imagine pero no sabia como armar el codigo. Mil gracias por tu apoyo

    C. Zapata

    viernes, 16 de marzo de 2012 2:34