2009-07-29 17 views
9

Mam właściwość typu int w moim modelu widoku, który jest powiązany z TextBox. Wszystko działa poprawnie, TwoWay prace wiążące porządku z wyjątkiem jednego przypadku -Powiązanie WPF nie działa poprawnie z właściwościami typu int

Gdybym wyczyścić wartość TextBox, seter nieruchomość nie jest wywoływana i chociaż wartość jest kasowana w TextBox, nieruchomości nadal posiada poprzednią wartość.

ma ktoś napotkał podobny problem? czy istnieje jakieś obejście tego problemu?

Oto nieruchomość -

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

Oto jak ja wiążące własności w XAML -

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

Jestem ciekawy, czy to zachowanie jest takie samo w silverlight czy nie? Ktoś! – akjoshi

+0

To samo zachowanie w Silverlight, z wyjątkiem właściwości wiązania danych, takich jak NotifyOnSourceUpdated i UpdateSourceTrigger, które nie są obsługiwane w Silverlight. –

Odpowiedz

25

miałem podobny problem.

Wystarczy zaktualizować kod jako:

<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

wielkie dzięki! działa jak wdzięk –

+1

dla .net 3.5 lub nowszego, spróbuj 'TargetNullValue = ''' – walterhuang

6

Jest to częściowo domyślać (nie mam teraz VS przydatny do wypróbuj go), ale myślę, że dzieje się tak dlatego, że wyczyszczone pole tekstowe jest pustym string (""), którego nie można niejawnie przekonwertować na int. Prawdopodobnie należy zaimplementować konwerter typów, aby zapewnić konwersję za Ciebie. (prawdopodobnie chcesz zrobić coś podobnego do konwersji "" na 0)

+0

Najprostszym sposobem sprawdzenia - uruchom swój projekt w Visual Studio i obserwuj okno Output (View-Output). Po wyczyszczeniu pola tekstowego powinien pojawić się błąd wiązania, o którym Simon mówi. –

+0

Mam VS pod ręką, i masz rację. +1 –

0

Jest tak, ponieważ wartość int nie może być null. Najlepiej użyć właściwości string, która konwertuje wartość w twoim kodzie na wymagane pole właściwości int.

W ten sposób można wykonać

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

A w dół z jakiego powodu? – ChrisBD

+1

Nie widzę w tym nic złego. Zdobądź ode mnie +1. Chociaż myślę, że preferowanym sposobem byłby raczej konwerter typów niż duplikat. –

+0

Dziękuję. Zapytałem tylko, czy coś przeoczyłem. Konstruktywna krytyka jest zawsze mile widziana, bo jak inaczej uczymy się na własnych błędach? – ChrisBD

1

Akjoshi Mam roztwór roboczy!

Musisz zmienić swoje właściwości Integer do Naullable<int> (tj int?), patrz poniższy fragment:

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

Trzeba także dodać konwerter wartości konwersji pusty łańcuch na wartość null, zobacz następujący fragment kodu:

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 
} 

Kod 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> 

[Uwaga: jest to tylko dowód koncepcji, a dla uproszczenia nie używałem żadnych wzorów lub najlepsze praktyki]

6

Jeśli nie chcesz korzystać z Nullableinteger, ty można użyć converter który konwertuje pusty string 0, patrz poniższy kod:

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

Dzięki Mohammedowi, ale rozwiązanie to zostało już wspomniane przez "Simona" rok temu. – akjoshi

+0

Z korzyścią dla wyszukiwarek, znalazłem ten konwerter wartości (http://www.codecisions.com/custom-ivalueconverter-for- binding-a-popf-textbox-to-an-integer/) utrzymał pole tekstowe jako puste zamiast zmieniać ją na zero na pierwszym planie, jak wydaje się to robić. Oczywiście zależy od wymagań, do których się wybierasz. – HockeyJ

0

mam ten sam problem, ale trzeba obsłużyć, a nie wartość liczbową.Używam następującego konwertera:

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; 
     } 
    } 
} 
Powiązane problemy