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,问题解决!

   

 

posted on   backslash112  阅读(5747)  评论(2编辑  收藏  举报

编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架

导航

点击右上角即可分享
微信分享提示