views:

29

answers:

3

I've got a data template for a list box item similar to the one on this page... link

I would like to take it a step further and do something to highlight the items when they change. For example, using the code in the link above, I would like to put a trigger to do something when Widget.Quantity changes. Maybe make the quiantity item (nothing else) flash or something. How can I do that? I include the relevant code below...

    <Window.Resources>
    <Style x:Key="RoundedItem" TargetType="ListBoxItem">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBoxItem">
                    <Border CornerRadius="10" BorderBrush="Black" BorderThickness="1" Margin="1">
                        <ContentPresenter />
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <DataTemplate DataType="{x:Type local:Widget}">
        <StackPanel Orientation="Horizontal">
            <Label Content="{Binding Name}" />
            <Label Content="{Binding Quantity}" />
        </StackPanel>
    </DataTemplate>
</Window.Resources>
<ListBox ItemsSource="{Binding Widgets}" ItemContainerStyle="{StaticResource RoundedItem}" HorizontalContentAlignment="Stretch" />
+1  A: 

Just add triggers to the DataTemplate.Triggers collection.

<DataTemplate DataType="{x:Type local:Widget}">
    <StackPanel x:Name="panel" Orientation="Horizontal">
        <Label Content="{Binding Name}" />
        <Label Content="{Binding Quantity}" />
    </StackPanel>

    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding SomeProperty}" Value="True">
            <Setter Property="Background" Value="Yellow" TargetName="panel" />
        </DataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>
siz
Yeah I've used something similar before to get the listboxitem background to change when the whole item is selected. I want to detect when something within an item changes and then apply some kind of effect to that sub item. In the example code given, I would like to know when the value of <Label Content="{Binding Quantity}" />changes and then make that Label control flash (or do something visible anyway).
A: 

You'll probably want to add a property in your Widget class to do that. Or if Widget is a Model, you may want to wrap it in a WidgetViewModel class with an "IsFlashing" property on it. Then set the trigger to fire whenever this "IsFlashing" property is True.

karmicpuppet
I've just discovered EventTriggers and think that is the way to go, since I want to do something whenever a value changes (don't care what the value is).
EventTriggers depend on RoutedEvents so it's not as easy as just hooking up to PropertyChanged or a new event on your VM.
John Bowen
A: 

I've managed to get it working with EventTriggers. Complete code below. In summary, the event trigger detects when the bound value changes, then turns the text orange briefly.

    <UserControl.Resources>
    <!-- instantiate an instance of the TimeSettingsCollection class -->
    <c:TimeSettingsCollection x:Key="TimeSettingsCollection"/>

    <Style x:Key="ListBoxItemStyle" TargetType="ListBoxItem">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBoxItem">
                    <Border Name="ItemBorder" BorderBrush="Gray" BorderThickness="1" Margin="3" Padding="7" Background="Transparent">
                        <ContentPresenter />
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsSelected" Value="True">
                            <Setter TargetName="ItemBorder" Property="Background" Value="LightBlue" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <DataTemplate DataType="{x:Type c:TimeSettingsItem}">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="80"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>

            <TextBlock Grid.Row="0" Grid.Column="0" Margin="0,0,8,0" 
                       Style="{StaticResource smallTitleStyle}">Pc Name:</TextBlock>
            <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Path=PcName}" 
                       Style="{StaticResource textStyleTextBlock}"/>
            <TextBlock Grid.Row="1" Grid.Column="0" Margin="0,0,8,0" 
                       Style="{StaticResource smallTitleStyle}">Time:</TextBlock>
            <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding Path=TimeSettings.DateTime, NotifyOnTargetUpdated=True}" 
                       Style="{StaticResource textStyleTextBlock}" x:Name="timeTextBlock">
                <TextBlock.Background>
                    <SolidColorBrush Color="Transparent"/>
                </TextBlock.Background>
                <TextBlock.Triggers>
                    <EventTrigger RoutedEvent="Binding.TargetUpdated">
                        <BeginStoryboard>
                            <Storyboard>
                                <ColorAnimation
                                Storyboard.TargetName="timeTextBlock" 
                                Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)"
                                To="Orange"              
                                Duration="0:0:1"
                                AutoReverse="True"/>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>                    
                </TextBlock.Triggers>
            </TextBlock>
        </Grid>
    </DataTemplate>
</UserControl.Resources>


<DockPanel>
    <ListBox Name="timeListBox" ItemsSource="{Binding Source={StaticResource TimeSettingsCollection}}" ItemContainerStyle="{StaticResource ListBoxItemStyle}" HorizontalContentAlignment="Stretch" IsSynchronizedWithCurrentItem="True">
    </ListBox>
</DockPanel>