WPF触发器之数据触发器(B)

如果你还不知道数据触发器怎么使用,或者连数据触发器是什么都还不了解,请先阅读WPF触发器之数据触发器(A)

1. 当你知道了数据触发器是当某个.NET属性值变化时触发的操作,比如说当数字变成了 "8",那就让数字变成红色。那么使用数据触发器实现此功能就可以这样写:

<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self},Path=Text}" Value="8"> ...

2. 问题来了——可是,当 "DataTrigger" 的 "Value" 是一个变量值你要怎么办呢??

  

    如果你了解过WPF绑定,你可能会先想到这样来修改你的代码:

<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self},Path=Text}" Value="{Binding Path=RedNumber}"> ...

    运行程序,编译器会抛出一个错误使用导致的异常:

   

   

    此异常说不能在 "Datatrigger" 的 "Value" 属性上使用 "Banding" ,原因是它不是一个依赖属性。只有依赖属性可以使用 “Binding" 。

    关于此异常的详细信息,请大家自行查阅 ”Binding“ 和 ”依赖属性“ 的说明,在这里不做过多解释。

3. 这个问题,在MSDN技术论坛有人进行了探讨:如何在DataTrigger的Value中设定程序级变量? UserControl中如何绑定窗体变量?

4. 解决方案。

    使用多重绑定,关于WPF "多重绑定" 的知识,请查看MSDN文档,在这里也不做过多解释。查看 "多重绑定" 请点击这里

    此问题是因为不使用固定的值 "8" 来进行数字红色显示引起的,而是需要根据变量 "InputValue" 决定。

    所以,此解决办法的原理是把变量值 "InputValue" 和当前的值 "NowValue" 都传入某个方法,返回一个布尔值,表示 "InputValue" 和 "NowValue" 是否相等。

    这样,就可以把 Value="{Binding Path=RedNumber}"转换为 Value="true",即把变化值转化为布尔值 “true”。

 

    下面给出具体步骤:

    多重绑定需要使用多值转换器。

    <a> 首先定义一个多值转换器类:TimeIsUpConverter。代码如下:

 1 public class TimeIsUpConverter : IMultiValueConverter
 2 {
 3     public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
 4     {
 5         if (values == null)
 6             return false;
 7 
 8         string strInputValue = values[0].ToString();
 9 
10         int inputValue = 0;
11         bool inputValueIsNumber = int.TryParse(values[0].ToString(), out inputValue);
12         int nowTime = 0;
13         bool nowValueIsNumber = int.TryParse(values[1].ToString(), out nowTime);
14 
15         if (inputValueIsNumber && nowValueIsNumber)
16         {
17             return inputValue == nowTime;
18         }
19         return false;
20     }
21 
22     public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
23     {
24         throw new NotImplementedException();
25     }
26 }

    <b> 在xaml文件中引用刚刚定义转换器。

<UserControl xmlns:views="clr-namespace:TimerWarningApp.Views" ...
<UserControl.Resources>
    <views:TimeIsUpConverter x:Key="timeIsUpConverter" />
</UserControl.Resources>

    <c> 修改数据转换器的代码:

<Style.Triggers>
    <DataTrigger>
        <DataTrigger.Binding>
            <MultiBinding Converter="{StaticResource ResourceKey=timeIsUpConverter}">
                <Binding ElementName="tbInputValue"
                         Path="Text" />
                <Binding ElementName="tbNowValue"
                         Path="Text" />
            </MultiBinding>
        </DataTrigger.Binding>
        <DataTrigger.Value>true</DataTrigger.Value>
    </DataTrigger>
</Style.Triggers>

   OK,问题解决!

   

作者:backslash112 (美国CS研究生在读/机器人工程师)
出处:http://sirkevin.cnblogs.com
GitHub:https://github.com/backslash112
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
原文地址:https://www.cnblogs.com/sirkevin/p/2715856.html