Как вы можете заставить XAML TextBlock свернуть, когда он не содержит данных?
Я хочу сказать 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 с триггером стиля создает ошибку Тип '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, но даже тогда оба Try # 2 и Try # 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>
Итак, как мне это сделать?
Ответ:
ОК, так что это была безумная синтаксическая охота со счастливым концом, вот версия, которая работает, надеюсь, что это поможет кому-то, извлеченные уроки:
- если триггер, затем стиль
- if 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>
Ответы
Ответ 1
Либо Try # 2, либо Try # 3 должны быть в порядке - проблема в строке, где вы ссылаетесь на стиль - вам нужно использовать либо "Style =" {StaticResource [KeyName]} "или" Style = "{DynamicResource [KeyName]}".
Попробуйте это (в Try # 2):
<StackPanel Margin="10">
<TextBlock Style="{StaticResource MainMessageStyle}" Padding="10" Background="Yellow" Text="{Binding MainMessage}"/>
</StackPanel>
В Try 1 вы обнаруживаете ограничение текущих версий WPF: триггеры не поддерживаются непосредственно на элементах.
Ответ 2
Самый простой, простой и быстрый способ - это конвертеры. Итак, почему бы не 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}}" />
Поскольку вы будете использовать ваши конвертеры в нескольких проектах, реализуйте классы конвертеров в "общей библиотеке".
Ответ 3
Я думаю, что самый простой способ сделать это - определить конвертер, который преобразует строку в видимость.
...
return string.IsNullOrEmpty(s) ? Visibility.Collapsed : Visibility.Visible;
}
Тогда просто
<TextBlock Visibility="{StaticResource StringToVisibilityConverter}"