2009-07-29 8 views
9

J'ai une propriété de int tapez dans mon modèle de vue qui est lié à un TextBox. Tout fonctionne correctement, TwoWay œuvres liseréest sauf dans un cas -liaison WPF ne fonctionne pas correctement avec les propriétés de type int

Si j'effacer la valeur de TextBox, poseur de propriété n'obtient pas et bien que la valeur appelés est effacée en TextBox, propriété détient encore la valeur précédente.

Quelqu'un at-il rencontré un problème similaire? existe-t-il une solution de contournement pour cela?

Voici la propriété -

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

Voici comment je lient la propriété en XAML -

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

Je suis curieux de savoir si ce comportement est le même dans silverlight ou pas? N'importe qui! – akjoshi

+0

Même comportement dans Silverlight, à l'exception des propriétés de liaison de données telles que NotifyOnSourceUpdated et UpdateSourceTrigger qui ne sont pas prises en charge dans Silverlight. –

Répondre

25

J'ai eu le même problème.

Vous avez juste besoin de mettre à jour le code comme:

<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 =" espace de noms clr: System; assembly = mscorlib "' – Alain

+0

merci beaucoup !! fonctionne comme un charme –

+1

pour .net 3.5 ou supérieur, essayez 'TargetNullValue = ''' ' – walterhuang

6

Ceci est en partie une supposition (je n'ai pas VS à portée de main en ce moment à essayez-le), mais je pense que c'est parce qu'une zone de texte effacée est vide string (""), qui ne peut être implicitement convertie en int. Vous devriez probablement avoir implémenté un convertisseur de type pour fournir la conversion pour vous. (vous voulez probablement faire quelque chose comme convertir "" en 0)

+0

Méthode la plus simple à vérifier: exécutez votre projet dans Visual Studio et observez la fenêtre de sortie (View-Output). Lorsque vous effacez la zone de texte, vous devriez voir l'erreur de liaison dont parle Simon. –

+0

J'ai VS à portée de main, et vous avez raison. +1 –

0

C'est parce qu'une valeur int ne peut pas être null. Il est préférable d'utiliser une propriété string qui convertit la valeur de votre code dans le champ de propriété int requis.

De cette façon, vous pouvez effectuer une

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

Et le vote baissier pour quelle raison? – ChrisBD

+1

Je ne vois rien de mal à cela. Avoir un +1 de moi. Bien que je pense que le moyen préféré serait un convertisseur de type plutôt que d'une propriété en double. –

+0

Merci. J'ai seulement demandé au cas où j'avais manqué quelque chose. Les critiques constructives sont toujours les bienvenues, comment pouvons-nous apprendre de nos erreurs? – ChrisBD

1

Akjoshi, j'ai une solution de travail!

Vous devez changer votre propriété entière à Naullable<int> (c.-à-int?), voir l'extrait suivant:

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

Vous devez également ajouter un convertisseur de valeur pour convertir la chaîne vide null valeur, consultez le extrait de code:

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 
} 

Le code 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> 

[Note: ceci est juste une preuve de concept, et par souci de simplicité, je ne pas utiliser des modèles ou des meilleures pratiques]

6

Si vous ne souhaitez pas utiliser un Nullableinteger, vous peut utiliser un converter qui convertit le string vide à 0, voir le code ci-dessous:

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

Merci Mohammed, mais cette solution a déjà été mentionnée par 'Simon' il y a un an. – akjoshi

+0

Pour le bénéfice des chercheurs, j'ai trouvé ce convertisseur de valeur (http://www.codecisions.com/custom-ivalueconverter-for-binding-a-wpf-textbox-to-an-integer/) qui a laissé la zone de texte affichée vide plutôt que de le changer à zéro au premier plan comme cette réponse semble faire. De toute évidence, cela dépend de vos exigences. – HockeyJ

0

J'ai le même problème, mais je dois gérer et non à valeur numérique.J'utilise le convertisseur suivant pour cela:

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; 
     } 
    } 
} 
Questions connexes