【发布时间】:2011-09-24 09:15:08
【问题描述】:
我正在尝试将我的一些 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,任何数据都会立即触发触发器。
我意识到我可以在这里使用转换器,但我可以想到我想使用触发器的情况,我想知道是否有什么我可以做的。
【问题讨论】:
-
嗨...测试了您的困境并遇到了同样的问题。可悲的是,当我们从 WPF 下降到 Silverlight 及以下时会发生这种情况:o( 不知道是否存在解决方案,但我创建了一个转换器来完成这项工作,它使用初始值工作。跨度>
-
感谢 NestorArturo:是的,在我发布此内容后,我尝试使用转换器完成相同的操作,它似乎可以满足我的需求。听听任何 WPF/Silverlight 专家对单独转换器与纯粹基于 XAML 的方法的优点有何看法会很有趣。对于显示/隐藏控件之类的事情,我一直发现 DataTrigger 方法更透明一些,尽管我想你可能会争辩说,通过使用转换器,最终你会得到一个不那么混乱的标记。
-
您可能会看到这种行为,因为 DataTrigger 是从 PropertyChangeTrigger 派生的,并且在您的情况下, Name 属性最初没有改变。或者它可能是一个错误。您可以使用 .net 反射器查看 DataTrigger 实现以进行确认。我之前使用过 DataTriggers,但我没有遇到这个问题可能是因为我使用了可视状态管理器并从默认状态开始。您可以尝试强制执行所需行为的一种方法是在加载 XAML 后设置 Name 值。
-
好的,谢谢@Denis。我最近一直想弄清楚的是如何使用 VisualStateManager 来响应数据的变化。我见过的所有例子都是关于响应按钮按下事件等,我还没有真正看到任何关于绑定到数据的内容。对此有什么想法吗?
-
我对这类事情使用数据触发器和 gotostate 操作。在我看来,这是最符合 MVVM 的方式。例如:在我的视图模型中,我有一个可以设置为 Loading、Loaded 和 Failed 的属性。在我看来,我创建了 3 个绑定到属性并包含相应 GoToState 操作的 DataTrigger。为了让案例比属性控件更轻松,我创建了将属性直接绑定到可视状态组的简单行为。