I want to tell WPF: "If TextBlock contains no data, then don't show it."
TRY #1 with a simple trigger produces the error "'Text' member is not valid because it does not have a qualifying type name.":
<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 with a style trigger produces the error The type 'style' does not contain a public type-converter class:
<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 with a style DataTrigger produces the same error The type 'style' does not contain a public type-converter class:
<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: OK, that was a dumb oversight of mine, forgot the StaticResource, but even then both Try #2 and Try #3 get a new error The type System.Windows.Trigger in Style is unknown:
<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>
So how do I do this?
OK, so that was a maddening syntax hunt with a happy end, here's the version that works, hope it helps somebody, lessons learned:
code that works:
<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>
The easiest, simplest and quickest way are converters. So, why not KISS? (keep it simple, stupid)?
To implement converter classes only a few lines of code are necessary.
Converter:
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:
Include namespace:
xmlns:c="clr-namespace:Hfr.Windows.Controls"
Define resource:
<c:StringToVisibilityConverter x:Key="StringToVisiblity"/>
Use it:
<TextBlock
Text="{Binding SomeStringPropertyValue}"
TextWrapping="Wrap"
Visibility="{Binding SomeStringPropertyValue, Converter={StaticResource StringToVisiblity}}" />
Since you'll use your converters in multiple projects, implement the converter classes in a "common library".
Either Try #2 or Try #3 should be fine - the problem is in the line where you are referencing the style - you need to use either 'Style="{StaticResource [KeyName]}"' or 'Style="{DynamicResource [KeyName]}"'.
Try this (in Try #2):
<StackPanel Margin="10">
<TextBlock Style="{StaticResource MainMessageStyle}" Padding="10" Background="Yellow" Text="{Binding MainMessage}"/>
</StackPanel>
In Try 1 you reveal a limitation of current WPF versions: Triggers are not supported directly on elements.
I think the simplest way to do this would be to define a Converter which converts string to visibility.
...
return string.IsNullOrEmpty(s) ? Visibility.Collapsed : Visibility.Visible;
}
Then just
<TextBlock Visibility="{StaticResource StringToVisibilityConverter}"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With