2013-03-12 25 views
6

Jak używać IValueConverter do konwertowania wartości null na wartości logiczne?Null To Boolean IValueConverter nie działa

Używam wpf, aby spróbować wyświetlić kilka wartości logicznych (w polach wyboru). Po utworzeniu nowego rekordu wartości te są puste i pojawiają się w polach wyboru jako "nieokreślone". Chcę, aby pojawiły się wartości zerowe i zapisać jako "fałszywe" wartości.

Próbowałem utworzyć konwerter NullToBoolean, który pobiera wartości puste z bazy danych i wyświetla je jako fałszywe, , a następnie zapisuje je jako fałszywe, gdy użytkownik zapisuje dane. (Zasadniczo staram się uniknąć tego, że użytkownik musi kliknąć dwa razy w polach wyboru (raz, aby uczynić go prawdziwym, a następnie ponownie, aby uczynić go fałszywym) .To wydaje się działać na import - tj. Wartości puste są pokazane jako fałszywe - ale chyba robię dwa kliknięcia tańczyć wartość nie zmienia się w bazie danych przy zapisywaniu

My Converter.

[ValueConversion(typeof(bool), typeof(bool))] 
public class NullBooleanConverter : IValueConverter 
{ 

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
    if (value != null) 
    { 
     return value; 
    } 
    return false; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
    if (value != null) 
    { 
     return value; 
    } 
    return null; 
    } 
} 

Jednym z wyboru Próbuję mieć pracę Converter z:

<CheckBox Grid.Column="1" Grid.Row="0" Padding="5" Margin="5" VerticalAlignment="Center" Name="chkVarianceDescriptionProvided" IsThreeState="False"> 
     <CheckBox.IsChecked> 
     <Binding Path="VarianceDescriptionProvided" Mode="TwoWay"> 
      <Binding.Converter> 
      <utils:NullBooleanConverter /> 
      </Binding.Converter> 
     </Binding> 
     </CheckBox.IsChecked> 
    </CheckBox> 

Nie wiem, czy problem polega na tym, że mój kod jest błędny, czy jest to przypadek Konwertera myśli, że nic się nie zmieniło, dlatego nie musi być ConvertBack. Próbowałem wszystkich Mode s i przełączam kod w Konwertuj za pomocą ConvertBack, ale nic nie działa.

Czy ktoś może wskazać, co muszę zrobić, aby to naprawić?

+1

Człowiek, który wygląda brzydko. Czy konwersja wartości Null na false i not-null na true? Ponieważ tego nie robisz. i po konwersji, konwertujesz bool (który nigdy nie będzie zerowy) z powrotem do bool. –

+1

Czy sprawdziłeś, czy twój kod konwertera uderza? –

+3

Nawiasem mówiąc: "Po utworzeniu nowego rekordu wartości te są zerowe ..."to jest problem, napraw to. Powinieneś robić" View Friendly "ViewModels/DataModels –

Odpowiedz

1

Prawdziwy problem polega na tym, że nie inicjalizujesz swoich obiektów danych w pierwszej kolejności. Nie "naprawiaj", rób to dobrze na początek; budowniczych są dobre (na przykład). Powinieneś także tworzyć modele ViewModels/DataModels zamiast pracować bezpośrednio z Twoimi modelami (bazą danych itp.).

public class MyObjectBuilder 
{ 
    Checked _checked; 

    public MyObjectBuilder() 
    { 
      Reset() 
    } 

    private void Reset() 
    { 
      _checked = new Checked(true); //etc 
    } 

    public MyObjectBuilder WithChecked(bool checked) 
    { 
      _checked = new Checked(checked); 
    } 

    public MyObject Build() 
    { 
     var built = new MyObject(){Checked = _checked;} 
     Reset(); 
     return built; 
    } 
} 

wtedy zawsze zainicjować z budowniczym

myObjects.Add(new MyObjectBuilder().Build()); 

lub

myObjects.Add(_injectedBuilder.Build()); // Initialises Checked to default 
myObjects.Add(_injectedBuilder.WithChecked(true).Build()); //True 

Mimo to nie rozwiąże problemu Twojego hasła, będzie to naprawić swój podstawowy problem w sposób możesz Jednostka Test. np. można przetestować, aby upewnić się, że wartości dodane do listy obiektów są zawsze inicjowane.

+0

Dzięki @ Meirion-Hughes. Rozumiem, co masz na myśli, i możesz podążać za swoimi pomysłami, aby dotrzeć tam, gdzie chcę być. Domyślnie w konstrukcji obiektu - na nim. Nie wiedziałem o mvvm, kiedy zacząłem na tym, więc jest to obecnie wpf done old-skool (obsługa zdarzeń, trochę spaghetti, sprawdzanie poprawności danych itp. W kodzie z tyłu) z dodanymi funkcjami mvvm, kiedy uczę się jak je dopasować Dążąc do tego, aby mój kolejny projekt był w pełni mvvm, ale muszę przejść przez obecną hybrydę. Jeszcze raz dziękuję – mcalex

+0

Google, * Caliburn Micro *. To jest zajebiste. –

+0

Zbadałem kilka frameworków. Niestety żaden z nich nie wyjaśnia, w jaki sposób zamienić spaghetti w mvvm. Caliburn z pewnością robi wrażenie i może być tym, na czym rozpoczynam nowy projekt. Pozdrawiam – mcalex

0

Po prostu popraw dane przed wykonaniem wykonywania wiązania danych. To jedyna opcja. Konwerter będzie działał tylko, jeśli to pole wyboru będzie widoczne jako "niezaznaczone" i zaktualizuje dane tylko podczas interakcji z formantem. Na przykład:

foreach (var item in items) 
{ 
    if (item.VarianceDescriptionProvided == null) 
     item.VarianceDescriptionProvided = false; 
} 
+0

Nie powiedzie się, jeśli pozycje zostały dodane losowo, należy dodać listę obserwowalną, posłuchać i naprawić każdy nowy element dodany do ciebie równie dobrze może po prostu upewnić się, że są poprawne, kiedy je robisz. –

+0

Po prostu uruchom ten kod za każdym razem, gdy otrzymasz wynik z EF. Nie potrzeba skomplikowanych opakowań i takich –

13

Hmm, po co używać konwertera, jeśli możesz go wyjąć z pudełka?

<CheckBox IsChecked="{Binding VarianceDescriptionProvided, TargetNullValue=False}" /> 

Aby uzyskać więcej informacji, prosimy o zapoznanie się z here.

+0

Nie wiedziałem o TargetNullValue, wielkie dzięki. Jednak nie powoduje to zapisania wartości "Fałsz" z powrotem do bazy danych (tj. Po zapisaniu są one nadal NULL). Robi to samo, co obecnie konwerter, więc użyję go zamiast tego, podczas gdy naprawię mój większy problem. – mcalex

+0

OK, to była tylko próba. Nie byłem pewien, czy wartość zostanie przekazana do VM. Dzięki za informowanie mnie. :) – DHN

+0

Jest interesująca, ponieważ doco: (http://msdn.microsoft.com/en-us/library/system.windows.data.bindingbase.targetnullvalue.aspx) mówi, że jest to getter i seter - ale wtedy robi nie daje przykładu ustawienia. – mcalex