2009-07-29 8 views
9

Estoy teniendo una propiedad de int escriba en mi modelo de vista que está vinculado a un TextBox. Todo funciona correctamente, TwoWay obras vinculantes bien, excepto en un caso -WPF vinculante no funciona correctamente con las propiedades de int tipo

Si puedo borrar el valor de TextBox, organismo propietario no se vuelve a llamar y aunque el valor se borra en TextBox, propiedad todavía mantiene el valor anterior.

¿Alguien ha enfrentado un problema similar? ¿hay alguna solución para esto?

Aquí es la propiedad -

public int MaxOccurrences 
{ 
    get 
    { 
     return this.maxOccurrences; 
    } 
    set 
    { 
     if (this.maxOccurrences != value) 
     { 
      this.maxOccurrences = value; 
      base.RaisePropertyChanged("MaxOccurrences"); 
     } 
    } 
} 

Así es como estoy vinculante la propiedad en XAML -

<TextBox Text="{Binding Path=MaxOccurrences, Mode=TwoWay, 
    NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}" 
    HorizontalAlignment="Center" Width="30" Margin="0,0,5,0"/> 
+0

Tengo curiosidad por saber si este comportamiento es el mismo en Silverlight o no? ¡Nadie! – akjoshi

+0

Mismo comportamiento en Silverlight, excepto por las propiedades de enlace de datos como NotifyOnSourceUpdated y UpdateSourceTrigger que no son compatibles con Silverlight. –

Respuesta

25

tuve el mismo problema.

Usted sólo tiene que actualizar el código como:

<TextBox Text="{Binding Path=MaxOccurrences, Mode=TwoWay, TargetNullValue={x:Static sys:String.Empty}, 
NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}" 
HorizontalAlignment="Center" Width="30" Margin="0,0,5,0"/> 
+9

'xmlns: sys =" clr-namespace: System; assembly = mscorlib "' – Alain

+0

muchas gracias !! trabajando como un encanto –

+1

para .net 3.5 o superior, pruebe 'TargetNullValue = ''' – walterhuang

6

Esto es en parte una conjetura (no tengo VS útil en este momento para pruébalo), pero creo que es porque un cuadro de texto borrado está vacío string (""), que no se puede convertir implícitamente a int. Probablemente debería implementar un convertidor de tipo para proporcionar la conversión por usted. (Es probable que desee hacer algo como convertir "" a 0)

+0

La manera más fácil de verificar: ejecutar su proyecto en Visual Studio y ver la ventana de Salida (View-Output). Cuando borre el cuadro de texto, verá el error de enlace de que habla Simon. –

+0

tengo VS práctico, y tienes razón. +1 –

0

Es porque un valor de int no puede ser null. Lo mejor es usar una propiedad string que convierta el valor para usted dentro de su código en el campo de propiedad int requerido.

De esta manera se puede realizar una

if(string.IsNullOrEmpty(text)) 
{ 
    this.intValue = 0; 
} 
+0

¿Y el voto a la baja por qué? – ChrisBD

+1

No veo nada de malo en eso. Ten un +1 de mi parte Aunque creo que la forma preferida sería un convertidor de tipo en lugar de una propiedad duplicada. –

+0

Gracias. Solo pregunté en caso de que me hubiera perdido algo. La crítica constructiva siempre es bienvenida, ¿cómo aprendemos de nuestros errores? – ChrisBD

1

Akjoshi, tengo una solución de trabajo!

necesita cambiar su propiedad de entero a Naullable<int> (es decir int?), consulte el siguiente fragmento:

private int? _maxOccurrences; 
public int? MaxOccurrences 
{ 
    get { return _maxOccurrences; } 
    set { _maxOccurrences = value; } 
} 

También es necesario añadir un convertidor de valores para convertir la cadena vacía en nulo valor, consulte la siguiente fragmento de código:

public class EmptyStringToNullConverter : IValueConverter 
{ 
    #region IValueConverter Members 

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     return value; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     return value == null || string.IsNullOrEmpty(value.ToString()) 
      ? null 
      : value; 
    } 

    #endregion 
} 

El código XAML:

<Window x:Class="ProgGridSelection.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:System="clr-namespace:System;assembly=mscorlib" 
    xmlns:local="clr-namespace:ProgGridSelection" 
    Title="MainWindow" 
    Height="136" Width="525" 
    Loaded="OnWindowLoaded"> 
<Window.Resources> 
    <local:EmptyStringToNullConverter x:Key="EmptyStringToNullConverter"/> 
</Window.Resources> 
<StackPanel> 
    <Button Content="Using Empty String to Null Converter"/> 
    <TextBox Name="empNameTextBox" 
      Text="{Binding Mode=TwoWay, Path=MaxOccurrences, 
       RelativeSource={RelativeSource FindAncestor, AncestorType=Window}, 
       Converter={StaticResource EmptyStringToNullConverter}}"/> 
</StackPanel> 

[Nota: esto es sólo una prueba de concepto, y en aras de la simplicidad que no utilizó ningún patrón o mejores prácticas]

6

Si no desea utilizar un Nullableinteger, se puede utilizar un converter que convierte el vacío string a 0, ver el código de abajo:

public class EmptyStringToZeroConverter : IValueConverter 
{ 
    #region IValueConverter Members 

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     return value; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     return value == null || string.IsNullOrEmpty(value.ToString()) 
      ? 0 
      : value; 
    } 

    #endregion 
} 
+0

Gracias Mohammed, pero esta solución ya fue mencionada por 'Simon' hace un año. – akjoshi

+0

Para el beneficio de los buscadores, encontré que este convertidor de valor (http://www.codecisions.com/custom-ivalueconverter-for-binding-a-wpf-textbox-to-an-integer/) mantenía el cuadro de texto que se muestra como vacío en lugar de cambiarlo a un cero en primer plano, como parece hacer esta respuesta. Obviamente, depende de los requisitos a los que recurra. – HockeyJ

0

tengo el mismo problema, pero necesito de manejar y no al valor numérico.Yo uso el siguiente convertidor para esto:

public class StringFormatToIntConverter : IValueConverter 
{    
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
      return value.ToString(); 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     if(value is string) 
     { 
      var inttext = 
      System.Text.RegularExpressions.Regex.Replace((string)value, "[^.0-9]", ""); 

      int number; 
      return Int32.TryParse(inttext, out number) ? number : 0; 
     } 
     else 
     { 
      return value; 
     } 
    } 
} 
Cuestiones relacionadas