我正在尝试将我的一些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的数据对象,并像往常一样为Name属性引发PropertyChanged事件。如果我更改文本框的值并失去焦点,我会得到预期的行为,但是如果文本框的初始值设置为ReddenMe(对于这个设计的示例,我将其用作文本的红色触发器),文字不会变红。有谁知道这里发生了什么?对于WPF中的DataTriggers,将立即针对任何数据触发触发器。
我意识到我可以在这里使用转换器,但我可以想到我想要使用触发器的情况,我想知道我能做些什么才能使它工作。
答案 0 :(得分:11)
我在Tom Peplow的博客上找到了a solution:从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);
}
}