2009-06-08 8 views
15

Voglio dire WPF: "Se TextBlock non contiene dati, quindi non mostrarlo."Come si può ottenere un XAML TextBlock da comprimere quando non contiene dati?

TRY # 1 con un semplice scattoproduce l'errore "'Testo' membro è non valido perché non ha un nome di tipo di qualifica ":.

<StackPanel Margin="10"> 
    <TextBlock Padding="10" Background="Yellow" Text="{Binding MainMessage}"> 
     <TextBlock.Triggers> 
      <Trigger Property="Text" Value="{x:Null}"> 
       <Setter Property="Visibility" Value="Collapsed"/> 
      </Trigger> 
     </TextBlock.Triggers> 
    </TextBlock> 
</StackPanel> 

TRY # 2 con un trigger stile produce t egli error Lo 'stile' di tipo non contiene una classe di tipo convertitore pubblica:

<UserControl x:Class="TestItemsSource234.Views.SmartForm" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <UserControl.Resources> 
     <Style x:Key="MainMessageStyle" TargetType="TextBlock"> 
      <Style.Triggers> 
       <Trigger> 
        <Trigger Property="Text" Value="{x:Null}"> 
         <Setter Property="Visibility" Value="Collapsed"/> 
        </Trigger> 
       </Trigger> 
      </Style.Triggers> 
     </Style> 
    </UserControl.Resources> 
    <StackPanel Margin="10">   
     <TextBlock Style="MainMessageStyle" Padding="10" Background="Yellow" Text="{Binding MainMessage}"/> 
    </StackPanel> 
</UserControl> 

TRY # 3 con uno stile DataTrigger produce lo stesso errore Il tipo 'stile' non contiene una classe di tipo convertitore pubblica:

<UserControl x:Class="TestItemsSource234.Views.SmartForm" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <UserControl.Resources> 
     <Style x:Key="MainMessageStyle" TargetType="TextBlock"> 
      <Style.Triggers> 
       <Trigger> 
        <DataTrigger Binding="{Binding MainMessage}" Value="{x:Null}"> 
         <Setter Property="Visibility" Value="Collapsed"/> 
        </DataTrigger> 
       </Trigger> 
      </Style.Triggers> 
     </Style> 
    </UserControl.Resources> 
    <StackPanel Margin="10">   
     <TextBlock Style="MainMessageStyle" Padding="10" Background="Yellow" Text="{Binding MainMessage}"/> 
    </StackPanel> 
</UserControl> 

TRY # 4: OK, che era una svista muto di mine, dimenticato il StaticResource, ma anche allora sia provare 2 # 3 # e cercare ottenere un nuovo errore Il tipo System.Windows.Trigger in stile è sconosciuta:

<UserControl x:Class="TestItemsSource234.Views.SmartForm" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <UserControl.Resources> 
     <Style x:Key="MainMessageStyle" TargetType="TextBlock"> 
      <Style.Triggers> 
       <Trigger> 
        <Trigger Property="Text" Value=""> 
         <Setter Property="Visibility" Value="Collapsed"/> 
        </Trigger> 
       </Trigger> 
      </Style.Triggers> 
     </Style> 
    </UserControl.Resources> 
    <StackPanel Margin="10">   
     <TextBlock Style="{StaticResource MainMessageStyle}" Padding="10" Background="Yellow" Text="{Binding MainMessage}"/> 
    </StackPanel> 
</UserControl> 

Allora, come faccio a fare questo?

RISPOSTA:

OK, così che era una caccia sintassi esasperante con un lieto fine, ecco la versione che funziona, spero che aiuta qualcuno, lezioni apprese:

  • se grilletto, poi stile
  • se lo stile, quindi StaticResource
  • se vincolante, quindi DataTrigger

codice che funziona:

<UserControl x:Class="TestItemsSource234.Views.SmartForm" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <UserControl.Resources> 
     <Style x:Key="MainMessageStyle" TargetType="TextBlock"> 
      <Style.Triggers> 
       <DataTrigger Binding="{Binding MainMessage}" Value="{x:Null}"> 
        <Setter Property="Visibility" Value="Collapsed"/> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </UserControl.Resources> 
    <StackPanel Margin="10"> 
     <ItemsControl 
      ItemsSource="{Binding DataTypeViews}"/> 
     <TextBlock Style="{StaticResource MainMessageStyle}" Padding="10" Background="Yellow" Text="{Binding MainMessage}"/> 
    </StackPanel> 
</UserControl> 
+7

ugh. perché WPF è così terribile? – PeterAllenWebb

+2

Non c'è nessuna scusa per il team WPF per il motivo per cui # 4 non funziona! Perché la WPF è così criptica? –

risposta

2

O Prova 2 # o Prova 3 # dovrebbe andare bene - il problema è nella linea in cui si fa riferimento lo stile - è necessario utilizzare uno 'Stile = "{StaticResource [KeyName]}" 'o' Style = "{DynamicResource [KeyName]}" '.

Prova questa (in prova # 2):

<StackPanel Margin="10">   
    <TextBlock Style="{StaticResource MainMessageStyle}" Padding="10" Background="Yellow" Text="{Binding MainMessage}"/> 
</StackPanel> 

In Prova 1 si rivelano una limitazione di versioni attuali WPF: trigger non sono supportati direttamente su elementi.

+1

"I trigger non sono supportati direttamente sugli elementi." - Quindi il compilatore dovrebbe dirti questo, non un altro errore non correlato. –

1

Penso che il modo più semplice per farlo sarebbe quello di definire un convertitore che converta la stringa in visibilità.

... 

    return string.IsNullOrEmpty(s) ? Visibility.Collapsed : Visibility.Visible; 
} 

Poi basta

<TextBlock Visibility="{StaticResource StringToVisibilityConverter}" 
5

Il modo più semplice e veloce più semplice sono convertitori. Quindi, perché non KISS? (tienilo semplice, stupido)?

Per implementare le classi di convertitore sono necessarie solo poche righe di codice.

Converter:

public class StringToVisibilityConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     return string.IsNullOrWhiteSpace((string)value) ? Visibility.Collapsed : Visibility.Visible; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     var visiblity = (Visibility)value; 
     return visiblity == Visibility.Visible; 
    } 
} 

Usage:

Include namespace: xmlns:c="clr-namespace:Hfr.Windows.Controls"

Definire risorsa: <c:StringToVisibilityConverter x:Key="StringToVisiblity"/>

utilizzarlo:

<TextBlock 
    Text="{Binding SomeStringPropertyValue}" 
    TextWrapping="Wrap" 
    Visibility="{Binding SomeStringPropertyValue, Converter={StaticResource StringToVisiblity}}" /> 

Dal momento che userete i vostri convertitori in più progetti, implementare le classi di conversione in una "libreria comune".

Problemi correlati