2010-01-23 19 views

Odpowiedz

40

Można użyć ValueConverter:

<TextBlock 
    Visibility="{Binding InstanceName, Converter={local:StringNullOrEmptyToVisibilityConverter}}" 
    Text="{Binding InstanceName}"/> 

z następującym kodzie:

public class StringNullOrEmptyToVisibilityConverter : System.Windows.Markup.MarkupExtension, IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     return string.IsNullOrEmpty(value as string) 
      ? Visibility.Collapsed : Visibility.Visible; 
    } 
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     return null; 
    } 
    public override object ProvideValue(IServiceProvider serviceProvider) 
    {    
     return this; 
    } 
} 
+0

Widzę, że działa, ale to będzie bardzo nudne. Nie mogę przestać myśleć, że musi być lepszy sposób. –

+6

Jak myślisz, co byłoby nużącą częścią? Czy uważasz, że ustawienie zarówno widoczności, jak i tekstu może stać się nudne? czy tak myślisz ogólnie o przetwornikach wartości? Jedną z rzeczy, którą zmienię, jest powiązanie właściwości visibility z relatywnym źródłem z self = path name, aby nie powtarzać "InstanceName"! poza tym nie widzę, jak to może być nudne (zawsze można napisać własne MarkupExtensions lub nawet zachowanie, które może to zrobić, ale myślę, że to jest na topie, a wartością jest tylko właściwa rzecz) –

0

Umieszczając dodatkową właściwość w Twojej viewmodel które można powiązać atrybut widoczność:

public class ViewModel 
{ 
    public string InstanceName {...} 
    public string Visibility InstanceVisibility 
    { 
     get 
     { 
      return String.IsNullOrEmpty(InstanceName) ? Visibility.Collapsed : Visibility.Visible; 
     } 
} 
+1

Nie podoba mi się to. Model musi być współużytkowany przez wiele widoków, ale zachowanie jest potrzebne tylko dla tego. –

+1

Imo istnieje relacja jeden-do-jednego między widokami i modelami widoku. Jeśli masz widoki, które mają wspólną funkcjonalność, możesz wyodrębnić typowe elementy i być może umieścić je we wspólnej superklasie viewmodel. –

+0

To nie brzmi dobrze. Nie jestem zaznajomiony z "ViewModels", ale w klasycznym MVC wiele widoków może wiązać się z tą samą instancją modelu. W ten sposób możesz edytować w jednym oknie i wyświetlać je w czasie rzeczywistym w innym. –

3

Jeśli jesteś wewnątrz (DATA-) Szablon można wykorzystać wyzwala do tego.

przeciwnym razie MVVM matrycowy lub ValueConverter pomoże.

+0

Konwerter wartości +1 jest bardziej poprawny. –

+0

Oba wyzwalacze i ValueConverter są mniej testowalne. –

+2

Żadne z nich nie jest "testowalne", ponieważ jedynym rzeczywistym testem jest wizualna kontrola wyników pod kątem pożądanego efektu. –

0
<TextBlock Text="{Binding Path=InstanceName},FallbackValue={x:Null}"></TextBlock> 

Następnie dodać DataTrigger, aby sprawdzić wartość jest null i zmienić widoczność za pomocą Settera. To jest prosta metoda, z której korzystam.

+0

Interesujące. Ale to nie zadziała z InstanceName == String.Empty ... –

0

Ok, więc jest blisko z PyBinding:

<TextBlock Text="{Binding Path=InstanceName}" Visibility="{p:PyBinding BooleanToVisibility(IsNotNull($[.InstanceName]))}" ></TextBlock> 

muszę wymienić IsNotNull z czymś, co oznacza IsNotNullOrEmpty, ale jestem coraz bliżej.

Powiązane problemy