wpf - 当 XAML TextBlock 不包含数据时,如何让其折叠?

标签 wpf xaml triggers

我想告诉 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>

尝试#2 风格触发器 产生错误类型“样式”不包含公共(public)类型转换器类:
<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>

尝试#3 样式数据触发器 产生相同的错误类型“样式”不包含公共(public)类型转换器类:
<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 : 好吧,那是我的一个愚蠢的疏忽,忘记了静态资源 ,但即便如此 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>

那么我该怎么做呢?

回答:

好的,这是一个令人发狂的语法搜索,结果很愉快,这是有效的版本,希望它对某人有所帮助,吸取的教训:
  • 如果触发,则 款式
  • 如果是样式,则 静态资源
  • 如果绑定(bind),则 数据触发器

  • 有效的代码:
    <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>
    

    最佳答案

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

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

    转换器:

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

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

    关于wpf - 当 XAML TextBlock 不包含数据时,如何让其折叠?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/965292/

    相关文章:

    wpf - Avalon Dock float 窗口 - ShowInTaskBar

    xaml - ListBox Windows 10 通用 header

    c# - Prism AutoWireViewModel在 Release模式下引发异常

    集群中的 spring 集成 + cron + quartz ?

    mysql - 具有复杂可配置条件的触发器

    wpf - 来自 ToolTip 或 ContextMenu 的 RelativeSource 绑定(bind)

    c# - WPF 文本 block 不能多行

    c# - 在辅助监视器中创建 WPF 窗口时遇到问题

    .net - WPF动画StackPanel的宽度从0到自动?

    MySql - 运行触发器以在指定时间后更改列状态