Как вы можете заставить XAML TextBlock рухнуть, когда он не содержит данных? - PullRequest
15 голосов
/ 08 июня 2009

Я хочу сказать WPF: " Если TextBlock не содержит данных, не показывать их. "

TRY # 1 с простым триггером выдает ошибку " 'Текстовый' элемент недопустим, поскольку у него нет квалифицирующего имени типа. " :

<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 с триггером в стиле выдает ошибку Тип '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>

TRY # 3 с DataTrigger в стиле выдает ту же ошибку Тип '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 , но даже тогда обе попытки № 2 и № 3 получают новую ошибку Тип 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>

Так как мне это сделать?

ОТВЕТ:

Хорошо, это была сводящая с ума синтаксическая охота со счастливым концом, вот версия, которая работает, надеюсь, она кому-нибудь поможет, извлеченные уроки:

  • если триггер, то стиль
  • если стиль, то 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 ]

5 голосов
/ 28 марта 2013

Самый простой, простой и быстрый способ - это конвертеры. Так почему бы не поцеловать? (будь проще, глупый)?

Для реализации классов конвертера требуется всего несколько строк кода.

Преобразователь:

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:

Включить пространство имен: 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 голосов
/ 08 июня 2009

Либо Try # 2, либо Try # 3 должно быть в порядке - проблема в строке, где вы ссылаетесь на стиль - вам нужно использовать либо 'Style = "{StaticResource [KeyName]}" или «Style =" {DynamicResource [KeyName]} "'.

Попробуйте это (в попытке № 2):

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

В попытке 1 вы обнаружите ограничение текущих версий WPF: триггеры не поддерживаются непосредственно для элементов.

1 голос
/ 27 июля 2010

Я думаю, что самый простой способ сделать это - определить конвертер, который преобразует строку в видимость.

   ...

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

Тогда просто

<TextBlock Visibility="{StaticResource StringToVisibilityConverter}"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...