2009-06-08 8 views
15

Quiero decirle WPF: "Si TextBlock no contiene datos, entonces no lo muestran."¿Cómo se puede hacer colapsar un XAML TextBlock cuando no contiene datos?

TRY # 1 con una sencilla gatillo produce el error "miembro de 'Texto' es no es válido, ya que no tiene un nombre de tipo de clasificación ":.

<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 gatillo estilo produce t que error El 'estilo' de tipo no contiene una clase de tipo de convertidor pública:

<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 un estilo DataTrigger produce el mismo error El 'estilo' de tipo no contiene una clase de tipo convertidor pública:

<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, eso fue un descuido tonto de la mina, se olvidó de la StaticResource, pero incluso entonces ambos tratan # 2 y # 3 Tratar conseguir un nuevo error El tipo System.Windows.Trigger en el estilo es desconocida:

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

Entonces, ¿cómo lo hago?

RESPUESTA:

OK, así que fue una búsqueda de sintaxis enloquecedor con un final feliz, aquí está la versión que funciona, espero que ayude a alguien, las lecciones aprendidas:

  • si gatillo, a continuación, estilo
  • si el estilo, entonces StaticResource
  • si la unión, entonces DataTrigger

código que funciona:

<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. ¿Por qué wpf es tan horrible? – PeterAllenWebb

+2

¡No hay excusa para el equipo de WPF por qué el # 4 no solo FUNCIONA! ¿Por qué WPF es tan críptico? –

Respuesta

2

o bien tratar # 2 o Trate # 3 debe estar bien - el problema está en la línea donde se hace referencia al estilo - es necesario utilizar 'Estilo = "{StaticResource [KeyName]}" 'o' Style = "{DynamicResource [KeyName]}" '.

probar este (en TRY # 2):

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

en TRY 1 que muestres una limitación de las versiones actuales de WPF: Los desencadenantes no son compatibles directamente sobre los elementos.

+1

"Los disparadores no son compatibles directamente con los elementos". - Entonces el compilador debería decirte esto, no otro error no relacionado. –

1

Creo que la forma más sencilla de hacerlo sería definir un convertidor que convierta una cadena en visibilidad.

... 

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

A continuación, sólo

<TextBlock Visibility="{StaticResource StringToVisibilityConverter}" 
5

La forma más fácil, más rápido y sencillo son convertidores. Entonces, ¿por qué no KISS? (Que sea simple, estúpido)?

Para implementar clases de convertidor, solo se necesitan unas pocas líneas de código.

Convertidor:

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; 
    } 
} 

Uso:

Incluir espacio de nombres: xmlns:c="clr-namespace:Hfr.Windows.Controls"

Definir recursos: <c:StringToVisibilityConverter x:Key="StringToVisiblity"/>

usarlo:

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

Dado que vamos a usar sus convertidores de múltiples proyectos, implementar las clases de convertidor de en una "biblioteca común".

Cuestiones relacionadas