Silverlight DataTrigger не стреляет под нагрузкой - PullRequest
7 голосов
/ 28 июня 2011

Я пытаюсь преобразовать некоторые из моих навыков WPF в Silverlight и столкнулся с несколько странной проблемой в тестовом мини-приложении, над которым я работал.В WPF я привык использовать DataTriggers в стиле для настройки свойств элемента управления на основе свойств связанных данных.Я обнаружил, что некоторые сборки, связанные с Blend, позволяют вам делать что-то подобное в Silverlight, и я придумал что-то вроде этого, в котором я объявил следующие пространства имен:

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>

В этом примереУ меня есть объект данных, реализующий INotifyPropertyChanged и вызывающий событие PropertyChanged, как обычно для свойства Name.Я получаю ожидаемое поведение, если я изменяю значение текстового поля и теряю фокус, но если начальное значение текстового поля установлено на ReddenMe (который для этого надуманного примера я использую в качестве триггера для текста, который будет красным),текст не становится красным.Кто-нибудь знает, что здесь происходит?Для DataTriggers в WPF триггер будет запущен немедленно для любых данных.

Я понимаю, что мог бы использовать конвертер здесь, но я могу вспомнить ситуации, когда я хотел бы использовать триггеры, и мне интересно,я могу сделать что-нибудь, чтобы сделать эту работу.

1 Ответ

11 голосов
/ 29 марта 2012

Вот решение Я нашел в блоге Тома Пеплоу: наследуй от DataTrigger и заставь триггер оценивать условие при загрузке связанного с ним элемента.

Вот как вы можете его кодировать:

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);
    }
}
...