2
votes

I have a WPF style that I am applying to list box items. Currently, each item is bound to a KeyValuePair. I display the Key in a TextBlock inside the ListBoxItem:

<TextBlock Name="Label" Text="{Binding Key}" />

What I want to do is make the Style generic so that if the data is not a KeyValuePair, (maybe just a string), I can bind the data correctly to the TextBlock.

Is there a way to pass a parameter to a Style or DataTemplate or make the data binding generic?

My style:

<Style x:Key="ListBoxItemStyle" TargetType="ListBoxItem">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="ListBoxItem">
        <Border x:Name="Border" Padding="2" SnapsToDevicePixels="true" CornerRadius="4" BorderThickness="1">
          <TextBlock Name="Label" Text="{Binding Key}" />
        </Border>
        <ControlTemplate.Triggers>
          <MultiTrigger>
            <MultiTrigger.Conditions>
              <Condition Property="IsSelected" Value="True"/>
            </MultiTrigger.Conditions>
            <Setter TargetName="Border" Property="Background" Value="{StaticResource SelectionGradient}" />
          </MultiTrigger>
        <ControlTemplate.Triggers>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>
1
How about just working with a Converter? Have you tried it?Damascus
I haven't tried using a Converter, but that could possibly work. I'm open to any suggestion to get this to work.Joe W

1 Answers

2
votes

Let me give you a quick example. Let's say your TextBox contains a number, and you want it to be with a red Background if the number is negative, or with a green background if >= 0

Here is the style you'd write:

<TextBlock Text="{Binding Key}" >
  <TextBlock.Style>
    <Style TargetType="TextBox">
      <Setter Property="Background" Value="{Binding Key, Converter={StaticResource MyConverterResource}" />
    </Style>
  </TextBlock.Style>
</TextBlock>

Here is the converter you'd write:

public class MyConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        double source = (double)value;
        return source < 0 ? Brushes.Red : Brushes.Green;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        // We don't care about this one here
        throw new NotImplementedException();
    }
}

And, to access the converter in your xaml, you just have to do the following, assuming your converter is in the namespace MyNamespace:

<Window xmlns:my="clr-namespace:MyNamespace">
  <Window.Resources>
    <my:MyConverter x:Key="MyConverterResource">
  </Window.Resources?
  <!-- Your XAML here -->
</Window>

(of course you can put this in any Resources, may it be a UserControl or whatever ) This will allow you to call your converter by writing {StaticResource MyConverterResource}

And here, you'd have a conditional style, the converter deciding which color to set as a background according to one parameter, in my case, the value itself (but it can be whatever you want)