Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Silverlight DataTrigger not firing on load

I'm attempting to convert some of my WPF skills to Silverlight, and have run into a slightly odd problem in the test mini-app I've been working on. In WPF, I got used to using DataTriggers within a style to set up control properties based on properties of the bound data. I discovered that some assemblies related to Blend allow you to do something like this in Silverlight, and I came up with something like this, in which I've got the following namespaces declared:

xmlns:ia="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"  
xmlns:iv="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"


<DataTemplate x:Key="testItemTemplate">
        <StackPanel Orientation="Horizontal">
            <TextBox Text="{Binding Name, Mode=TwoWay}" x:Name="thing"/>                
            <iv:Interaction.Triggers>
                <ia:DataTrigger Binding="{Binding Name}" Value="ReddenMe" Comparison="Equal">
                    <ia:ChangePropertyAction TargetName="thing" PropertyName="Foreground" Value="Red">
                    </ia:ChangePropertyAction>
                </ia:DataTrigger>
            </iv:Interaction.Triggers>
        </StackPanel>
    </DataTemplate>

In this example, I've got a data object implementing INotifyPropertyChanged and raising the PropertyChanged event as usual for the Name property. I get the expected behaviour if I change the value of the textbox and lose focus, but if the initial value of the textbox is set to ReddenMe (which for this contrived example I'm using as the trigger for the text to be red), the text doesn't go red. Does anybody know what's going on here? For DataTriggers in WPF, the trigger would be fired immediately for any data.

I realise that I could use a Converter here, but I can think of situations where I'd want to use triggers, and I wonder if there's anything I could do to make this work.

like image 795
andrewmcc Avatar asked Jun 28 '11 14:06

andrewmcc


1 Answers

Here's a solution I found on Tom Peplow's blog: inherit from DataTrigger, and make the trigger evaluate the condition when its associated element is loaded.

Here's how you can code it:

public class DataTriggerEvaluateOnLoad : Microsoft.Expression.Interactivity.Core.DataTrigger
{
    protected override void OnAttached()
    {
        base.OnAttached();
        var element = AssociatedObject as FrameworkElement;
        if (element != null)
        {
            element.Loaded += OnElementLoaded;
        }
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        var element = AssociatedObject as FrameworkElement;
        if (element != null)
        {
            element.Loaded -= OnElementLoaded;
        }
    }

    private void OnElementLoaded(object sender, RoutedEventArgs e)
    {
        EvaluateBindingChange(null);
    }
}
like image 108
Samuel Jack Avatar answered Oct 21 '22 17:10

Samuel Jack