Idanis
Idanis

Reputation: 1988

Creating a watermark templated texblock wpf

I have the following code for placing a "WaterMark" TextBlock on any wpf control:

<TextBlock Text="Some Text" IsHitTestVisible="False" Foreground="Gray" HorizontalAlignment="Center" VerticalAlignment="Center" FontWeight="Normal">
    <TextBlock.Style>
        <Style TargetType="TextBlock">
            <Setter Property="Visibility" Value="Hidden"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding ElementName=FromFrameComboBox, Path=SelectedItem}" Value="{x:Null}">
                    <Setter Property="Visibility" Value="Visible"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TextBlock.Style>
</TextBlock>

In order to prevent duplicating these lines for every control I want to bind this TextBlock to, I wish to create a UserControl from it and use it like this:

<ComboBox x:Name="FromFrameComboBox" Grid.Row="0" Grid.Column="1" ItemsSource="{Binding OrDataContainers.ObjectsCollection, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalContentAlignment="Center" 
                              VerticalContentAlignment="Center" VerticalAlignment="Center" SelectedItem="{Binding OrDataContainers.SelectedObject, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="0,5,0,0"/>
<Wpf:WatermarkTextBlock x:Name="FromFrameComboBoxText" Text="Select Frame Number" Grid.Row="0" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center"/>

(I have placed the TextBlock definition in an included dll file, and it looks like this:

<TextBlock x:Class="Wpf.WatermarkTextBlock" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       IsHitTestVisible="False" Foreground="Gray" FontWeight="Normal">
<TextBlock.Style>
    <Style TargetType="TextBlock">
        <Setter Property="Visibility" Value="Hidden"/>
        <Style.Triggers>
            <DataTrigger Binding="{Binding ElementName=AvailableFrames, Path=SelectedItem}" Value="{x:Null}">
                <Setter Property="Visibility" Value="Visible"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</TextBlock.Style>

The thing is that the DataTrigger is binded to a control I currently have, in the application I'm developing: AvailableFrames, and if I wish to reuse this dll in another application, I'll need to change the DataTrigger binding.

Can such a thing be done?

Upvotes: 1

Views: 116

Answers (1)

igorushi
igorushi

Reputation: 1995

In this concrete case NullToVisibilityConverter will be a simpler solution

public class NullToVisibilityConverter : MarkupExtension, IValueConverter
{
    public Visibility NullValue { get; set; }
    public Visibility NotNullValue { get; set; }
    public NullToVisibilityConverter()
    {
        NullValue = Visibility.Collapsed;
        NotNullValue = Visibility.Visible;
    }
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value == null)
            return NullValue;
        return NotNullValue;
    }


    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }
}

usage example:

<ComboBox x:Name="FromFrameComboBox"/>
<TextBlock Visibility="{Binding SelectedItem, ElementName=FromFrameComboBox, 
                                Converter={local:NullToVisibilityConverter NullValue=Visible, NotNullValue=Hidden}}"/>

Upvotes: 1

Related Questions