chincheta73 chincheta73 - 3 months ago 14
C# Question

Set a trigger for first item in the list

My question is a follow-up question of this other post: What are the different triggers in WPF?

I want to set a trigger that triggers if the item is the first one in a listview (so I can add a extra text). Which type of trigger shall I use?

here is my code:

<ListView Grid.Row="1" Grid.Column="2" Name="contactList" Margin="0,0,0,0">
<ListView.ItemTemplate>
<DataTemplate>
<WrapPanel>
<TextBlock Text="{Binding Name}" />
<TextBlock>
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<Trigger <!-- what do I have to put here so it triggers when the item is the first one in the list? -->>
<Setter Property="Text" Value=" - this is the first item in the list!!"/>
<Setter Property="Foreground" Value="#7f8c8d"/>
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</WrapPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

Answer

You'll have to use a DataTrigger with a MultiBinding and a converter for this bad boy. Check it out.

First, your converter...

class IsFirstItemConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        ListView lv = (ListView)values[0];
        if (lv.Items[0].Equals(values[1]))
            return true;
        else
            return false;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Now reference it in App.xaml...

<local:IsFirstItemConverter x:Key="isFirstItem"/>

Now for the meat...

<ListView x:Name="lv" ItemsSource="{Binding Items}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <TextBlock>
                <TextBlock.Style>
                    <Style TargetType="{x:Type TextBlock}">
                        <!--Text property moved to here-->
                        <Setter Property="Text" Value="{Binding Name}"/>
                        <Style.Triggers>
                            <DataTrigger Value="True">
                                <DataTrigger.Binding>
                                    <MultiBinding Converter="{StaticResource isFirstItem}">
                                        <MultiBinding.Bindings>
                                            <Binding ElementName="lv"/>
                                            <Binding/>
                                        </MultiBinding.Bindings>
                                    </MultiBinding>
                                </DataTrigger.Binding>
                                <Setter Property="Text" Value="First item"/>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </TextBlock.Style>
            </TextBlock>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Notice you'll have to move the setter for the Text property into the style. Since explicit declarations in the control override any property setters in styles, you wont ever see the effect of the trigger unless you move it as shown. Hope this helps!