Silverlight DataTrigger 未在加载时触发

发布于 2024-11-17 07:46:52 字数 1342 浏览 1 评论 0原文

我正在尝试将我的一些 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,对于任何数据都会立即触发触发器。

我意识到我可以在这里使用转换器,但我可以想到我想要使用触发器的情况,并且我想知道是否可以做任何事情来实现这项工作。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

那小子欠揍 2024-11-24 07:46:52

这是解决方案我在 Tom Peplow 的博客上找到:从 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);
    }
}

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);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文