The other day I was designing a page in WPF, and wanted to show or hide a TextBlock depending on whether one date was after another.

Both dates were stored in properties on the DataContext of the page, so theoretically I could have gotten to either of them via a binding. I have an “AtLeastConverter” class which will return true if the supplied value is equal to or greater than the converter parameter, so I decided to use that.

So I wanted to do this:

<TextBlock.Style>
    <Style TargetType="TextBlock">
        <Style.Triggers>
            <DataTrigger Value="True">
                <DataTrigger.Binding>
                    <Binding Path="Date" 
Converter="{StaticResource AtLeast}"
ConverterParameter="{Binding Pig.WithholdDate}" /> </DataTrigger.Binding> <DataTrigger.Setters> <Setter Property="Visibility" Value="Hidden" /> </DataTrigger.Setters> </DataTrigger> </Style.Triggers> </Style> </TextBlock.Style>

The problem, of course, is that you can’t bind the ConverterParameter property – it has to be a fixed value. I could have created an IMultiValueConverter and passed both values in, but I figured if I was going to write code, I might as well take the YAGNI approach and write it just for this one page.

So here’s the equivalent code in the constructor of my page. It creates the same style in C#, and assigns the correct value to the ConverterParameter of the Binding without having to bind it (since I know it won’t change during the lifetime of the page):

WithholdWarning.Style = new Style
{
    TargetType = typeof(TextBlock),
    Triggers = 
    {
        new DataTrigger
        {
            Value = true,
            Binding = new Binding("Date") 
            {
                Converter = new AtLeastConverter(),
                ConverterParameter = _removal.Pig.WithholdDate 
            },
            Setters = 
            {
                new Setter 
                { 
                    Property = TextBlock.VisibilityProperty, 
                    Value = Visibility.Hidden 
                } 
            }
        }
    }
};
This is making use of C# 3’s wonderful object and collection initializer syntax, which really tidies up what could otherwise be very messy code. In the end, the C# doesn’t look dissimilar to the XAML – it just has more curly braces and no angle brackets. It’s nice to know that there’s always an alternative.