2015-03-02 11 views
9

Mam 3 właściwości, które próbuję powiązać z blokadą tekstu w XAML. Jedna jest warunkowa, a dwie pozostałe to ciągi, które chcę wyświetlić w zależności od tego warunkowego.Warunkowe wiązanie tekstu XAML

<TextBlock Text="{Binding TrueText}" Style="{StaticResource styleSimpleText}" Visibility="{Binding ShowTrueText, Converter={StaticResource boolToVisibilityConverter}}"/> 
<TextBlock Text="{Binding FalseText}" Style="{StaticResource styleSimpleText}" Visibility="{Binding ShowTrueText, Converter={StaticResource invertedBoolToVisibilityConverter}}"/> 

To działa, ale teraz bloki tekstowe muszą mieć różne nazwy. Czy mogę zamienić to w jeden blok tekstu z warunkową zawartością?

+0

Musisz powiązać je z członkiem klasy cs i zaimplementować OnPropertyChanged lub w inny sposób poradzić sobie ze zdarzeniem zmienionym właściwości: 'public string thisText {get {if (" conditions) {return "ten tekst" ;} else {return "ten inny tekst";}} // koniec get} end of member' wtedy twój element xaml będzie wyglądał jak link: ' 'I niektóre zasoby w [OnPropertyChanged.] (Https://msdn.microsoft.com/en-us/library/ms743695 (v = vs.110) .aspx) – CalebB

Odpowiedz

27

Można to osiągnąć za pomocą stylów i DataTrigger:

<TextBlock> 
    <TextBlock.Style> 
     <Style TargetType="TextBlock"> 
      <Setter Property="Text" Value="{Binding FalseText}"/> 
      <Style.Triggers> 
       <DataTrigger Binding="{Binding ShowTrueText}" Value="True"> 
        <Setter Property="Text" Value="{Binding TrueText}"/> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </TextBlock.Style> 
</TextBlock> 

Alternatywą byłoby użyć MultiBinding z wielu wartości Przelicznik:

<TextBlock> 
    <TextBlock.Text> 
     <MultiBinding Converter="{StaticResource TextConverter}"> 
      <Binding Path="TrueText"/> 
      <Binding Path="FalseText"/> 
      <Binding Path="ShowTrueText"/> 
     </MultiBinding> 
    </TextBlock.Text> 
</TextBlock> 

Przetwornica będzie wygląda tak:

public class TextConverter : IMultiValueConverter 
{ 
    public object Convert(
     object[] values, Type targetType, object parameter, CultureInfo culture) 
    { 
     var trueText = (string)values[0]; 
     var falseText = (string)values[1]; 
     var showTrueText = (bool)values[2]; 
     return showTrueText ? trueText : falseText; 
    } 

    public object[] ConvertBack(
     object value, Type[] targetTypes, object parameter, CultureInfo culture) 
    { 
     throw new NotSupportedException(); 
    } 
} 
1

Tak, można, po prostu zawinąć je w TextBlock następująco:

<TextBlock x:name="myTextBlock" Style="{StaticResource styleSimpleText}"> 
    <TextBlock Text="{Binding TrueText}" Visibility="{Binding ShowTrueText, Converter={StaticResource boolToVisibilityConverter}}"/> 
    <TextBlock Text="{Binding FalseText}" Visibility="{Binding ShowTrueText, Converter={StaticResource invertedBoolToVisibilityConverter}}"/> 
</TextBlock> 

Myślę jednak, że najlepszą odpowiedzią jest jeden dostarczone przez Clemens (stosując DataTrigger).

0

Można go ustawić w swoim modelu widoku i pozwolić mu określić, który tekst ma być wyświetlany.

private static readonly string TRUETEXT = "This is the text to show when true"; 
    private static readonly string FALSETEXT = "This is the text to show when false"; 

    private bool _myBooleanProperty; 
    public bool MyBooleanProperty 
    { 
     get { return _myBooleanProperty; } 
     set 
     { 
      if (_myBooleanProperty != value) 
      { 
       _myBooleanProperty = value; 
       OnPropertyChanged("MyBooleanProperty"); 
       OnPropertyChanged("ResultText"); 
      } 
     } 
    } 

    public string ResultText 
    { 
     get 
     { 
      return MyBooleanProperty ? TRUETEXT : FALSETEXT; 
     } 
    } 

Następnie wiąże się z nim za pomocą tylko jednego bloku tekstu. Nie potrzeba konwertera widoczności.
Jeśli istnieje stan, w którym nie powinien być wyświetlany żaden tekst, można to również wykonać.

<TextBlock Text="{Binding ResultText}" Style="{StaticResource styleSimpleText}" /> 
1

Moim zdaniem, najlepszym rozwiązaniem tego problemu byłoby to nowy obiekt łańcuch w viewmodel która zwraca albo TrueText lub FalseText zależności od trybu warunkowego. Przy takiej właściwości możesz po prostu użyć zwykłego wiązania.

public string TheNewProperty 
{ 
    get 
    { 
    return ShowTrueText ? TrueText : FalseText; 
    } 
} 

<TextBlock Text="{Binding TheNewProperty}" Style="{StaticResource styleSimpleText}"/> 
1

Sposób, w jaki robimy tego typu rzeczy dla MVVM jest stworzenie właściwości w swoim viewmodel dla tego. To pozwala na testowanie jednostki dla twojego stanu na viewmodelu.

Właściwość w twoim kodzie podglądu będzie wartością ciągu, do którego jest związana blokada tekstu. W pewnym momencie viewmodel określi wartość tego łańcucha na podstawie logiki warunkowej, której potrzebujesz.