如何让 XAML TextBlock 在不包含数据时折叠?

问题描述 投票:0回答:4

我想告诉WPF:“如果TextBlock不包含数据,那么就不要显示它。

使用简单触发器尝试#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>

使用 style 触发器尝试 #2 会产生错误类型“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>
                    <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>

使用 style DataTrigger 尝试 #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>

TRY #4:好吧,这是我的一个愚蠢的疏忽,忘记了StaticResource,但即便如此,Try #2 和 Try #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>
wpf xaml triggers
4个回答
6
投票

最简单、最简单、最快的方法就是转换器。那么,为什么不接吻呢? (保持简单,愚蠢)?

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

转换器:

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}}" />

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


2
投票

尝试 #2 或尝试 #3 应该没问题 - 问题出在您引用样式的行 - 您需要使用 'Style="{StaticResource [KeyName]}"' 或 'Style="{DynamicResource [密钥名称]}"'。

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

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

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


1
投票

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

   ...

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

然后就

<TextBlock Visibility="{StaticResource StringToVisibilityConverter}"

0
投票

我的 VB.net 解决方案

Public Class ContentToVisibilityConverter
            Implements IValueConverter
        
            Public Function Convert(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.Convert
                If value Is Nothing OrElse (TypeOf value Is String AndAlso String.IsNullOrWhiteSpace(DirectCast(value, String))) Then
                    Return Visibility.Collapsed 
                End If
                Return Visibility.Visible 
            End Function
        
            Public Function ConvertBack(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.ConvertBack
                Throw New NotImplementedException()
            End Function
End Class

XAML

<Window.Resources>
     <ResourceDictionary>
<ContentToVisibilityConverter x:Key="ContentToVisibilityConverter"/>
 </Window.Resources>

<TextBlock Text="{Binding Path=MyText,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
              Visibility="{Binding Path=Row.Value.Variantentext, Converter={StaticResource ContentToVisibilityConverter}}"
              ></TextBlock>
© www.soinside.com 2019 - 2024. All rights reserved.