WPF 在绑定表达式添加计算

2021-01-14 02:13

阅读:711

标签:checkbox   添加空格   定静   界面   notify   xmlns   invoke   with   value   

很多时候一些简单的使用绑定需要对绑定的源做处理就需要通过转换器,这样的代码写起来不好看 本文告诉大家通过一个简单的库可以实现在界面绑定的时候通过表达式不需要转换

首先通过 Nuget 安装 CalcBinding 库,注意 Nuget 的地址是 https://api.nuget.org/v3/index.json 如果没有找到这个库就请复制链接点击更新,再输入 CalcBinding 寻找

技术图片

在使用这个库之前需要引用命名空间,打开 MainWindow.xaml 文件,添加命名空间

xmlns:c="clr-namespace:CalcBinding;assembly=CalcBinding"

然后创建一个数据用来绑定

    public class ViewModel : INotifyPropertyChanged
    {
        public double A
        {
            get => _a;
            set
            {
                if (value.Equals(_a)) return;
                _a = value;
                OnPropertyChanged();
            }
        }

        public double B
        {
            get => _b;
            set
            {
                if (value.Equals(_b)) return;
                _b = value;
                OnPropertyChanged();
            }
        }

        public double C
        {
            get => _c;
            set
            {
                if (value.Equals(_c)) return;
                _c = value;
                OnPropertyChanged();
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private double _a = 1;
        private double _b = 2;
        private double _c;

        [NotifyPropertyChangedInvocator]
        private void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

这时在界面如果需要创建一个 TextBlock 绑定三个值 A + B + C 就可以通过下面的方法

        ="{c:Binding A+B+C}" HorizontalAlignment="Center" VerticalAlignment="Center">/TextBlock>

通过直接写表达式的方式就可以,十分简单

那如果需要加上一些常量怎么做,如计算 0.5*A+B 可以怎么写?

="{c:Binding 0.5*A+B}" />

修改一下界面然后运行

            >
                >
                    ="A=" />
                    ="{Binding A}" />
                /TextBlock>
                >
                    ="B=" />
                    ="{Binding B}" />
                /TextBlock>
                >
                    ="C=" />
                    ="{Binding C}" />
                /TextBlock>
                ="0.5*A+B" />
                ="{c:Binding 0.5*A+B}" />
            /StackPanel>
技术图片

如果此时的还有一些布尔量怎么办?打开 ViewModel 类添加下面代码

        public bool BoolA
        {
            get => _boolA;
            set
            {
                if (value == _boolA) return;
                _boolA = value;
                OnPropertyChanged();
            }
        }

        public bool BoolB
        {
            get => _boolB;
            set
            {
                if (value == _boolB) return;
                _boolB = value;
                OnPropertyChanged();
            }
        }

        private bool _boolB;
        private bool _boolA = true;

如果需要绑定 A 和 B 可以这样写

="{c:Binding BoolA and BoolB}" />
="{c:Binding BoolA or BoolB}" />
="{c:Binding BoolA and BoolB or BoolB}" />

修改一下界面

            >
                >
                    ="A=" />
                    ="{Binding BoolA}" />
                /TextBlock>
                >
                    ="B=" />
                    ="{Binding BoolB}" />
                /TextBlock>
                ="A and B" />
                ="{c:Binding BoolA and BoolB}" />
                ="A or B" />
                ="{c:Binding BoolA or BoolB}" />
            /StackPanel>
技术图片

其他可以写的是表达式

="{c:Binding A+B+C}"/>
="{c:Binding A-B-C}"/>
="{c:Binding A*(B+C)}"/>
="{c:Binding 2*A-B*0.5}"/>
="{c:Binding A/B, StringFormat={}{0:n2} --StringFormat is used}"/> {with string format}
="{c:Binding A%B}"/>
="{c:Binding ‘(A == 1) ? 10 : 20‘}"/> {ternary operator}

判断布尔

="!IsChecked" IsChecked="{c:Binding !IsChecked}"/>
="{c:Binding ‘IsChecked and IsFull‘}"/> {‘and‘ is equvalent of ‘&&‘}
="{c:Binding ‘!IsChecked or (A > B)‘}"/> {‘or‘ is equvalent of ‘||‘, but you can leave ‘||‘}
="{c:Binding ‘(A == 1) and (B less= 5)‘}"/> {‘less=‘ is equvalent of ‘}
="{c:Binding (IsChecked || !IsFull)}"/>

因为在 xaml 不能使用 && || 所以需要使用 and or ‘less=’ 替换

另外对于 : 之前需要添加空格,如下面代码

="{c:Binding ‘(A == 2)?IsChecked : IsFull}"/> !-- right -->
="{c:Binding ‘(A == 2)?IsChecked :!IsFull}"/> !-- right -->
="{c:Binding ‘(A == 2) ? IsChecked :4 + IsFull}"/> !-- right -->

这些都是对的,但是下面的代码是无法运行

="{c:Binding ‘(A == 2)?IsChecked:IsFull}"/> !-- wrong -->

可以绑定静态的值,静态的值的写法 xmlNamespace:Class.StaticProperty.NestedProperty 命名空间下的类的静态属性的属性

对于经常计算值这里也可以简单使用,如 Math 里面的方法

="{c:Binding Math.Sin(A*Math.PI/180), StringFormat={}{0:n5} }"/>
="{c:Binding A*Math.PI}" />

枚举值也可以点命名空间的枚举的值,可以用来判断 xmlNamespace:EnumClass.Value 如在 Foo 枚举里面有 A 这个值

="{c:Binding ‘Foo==local:Foo.A‘}" />

经常会将 bool 转换为 Visibility 这个库也有简单的方法

如果需要在样式使用,需要通过 RelativeSource 找到方法

WPF 在绑定表达式添加计算

标签:checkbox   添加空格   定静   界面   notify   xmlns   invoke   with   value   

原文地址:https://www.cnblogs.com/GarsonZhang/p/12272047.html


评论


亲,登录后才可以留言!