如何在不包含数据的情况下让XAML TextBlock崩溃?

时间:2009-06-08 14:56:56

标签: wpf xaml triggers

我想告诉WPF:“如果TextBlock不包含任何数据,则不要显示它。

带有简单触发器

TRY#1 会产生错误“'Text'成员无效,因为它没有合格的类型名称。“:

<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 会产生错误“样式”类型不包含公共类型转换器类:< / p>

<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>
使用样式DataTrigger

TRY#3 会产生相同的错误类型'style'不包含公共类型转换器类

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

尝试#4 :好的,这是我的一个愚蠢的疏忽,忘了 StaticResource ,但即便如此,尝试#2和尝试#3都会出现新的错误 Style中的System.Windows.Trigger类型未知

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

那我该怎么做?

解答:

好的,这是一个令人发狂的语法搜索,有一个快乐的结局,这是有效的版本,希望它有助于某人,经验教训:

  • 如果触发,则样式
  • 如果是style,则 StaticResource
  • 如果绑定,则 DataTrigger

有效的代码:

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

3 个答案:

答案 0 :(得分:5)

最简单,最简单,最快捷的方式是转换器。所以,为什么不KISS? (保持简单,愚蠢)?

要实现转换器类,只需要几行代码。

<强>转换器:

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

<强>用法:

包含命名空间: xmlns:c="clr-namespace:Hfr.Windows.Controls"

定义资源: <c:StringToVisibilityConverter x:Key="StringToVisiblity"/>

使用它:

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

由于您将在多个项目中使用转换器,因此请在“公共库”中实现转换器类。

答案 1 :(得分:2)

尝试#2或尝试#3应该没问题 - 问题在于您引用样式的行 - 您需要使用'Style =“{StaticResource [KeyName]}”'或'Style =“ {DynamicResource [KeyName]}“'。

试试这个(在试验#2中):

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

在Try 1中,您揭示了当前WPF版本的限制:不直接在元素上支持触发器。

答案 2 :(得分:1)

我认为最简单的方法是定义一个将字符串转换为可见性的转换器。

   ...

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

然后只是

<TextBlock Visibility="{StaticResource StringToVisibilityConverter}"