title author date CreateTime categories
WPF 在绑定表达式添加计算
lindexi
2018-12-22 16:12:56 +0800
2018-12-22 15:43:54 +0800
WPF

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

首先通过 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 就可以通过下面的方法

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

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

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

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

修改一下界面然后运行

            <StackPanel>
<TextBlock>
<Run Text="A=" />
<Run Text="{Binding A}" />
</TextBlock>
<TextBlock>
<Run Text="B=" />
<Run Text="{Binding B}" />
</TextBlock>
<TextBlock>
<Run Text="C=" />
<Run Text="{Binding C}" />
</TextBlock>
<TextBlock Text="0.5*A+B" />
<TextBlock Text="{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 可以这样写

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

修改一下界面

            <StackPanel>
<TextBlock>
<Run Text="A=" />
<Run Text="{Binding BoolA}" />
</TextBlock>
<TextBlock>
<Run Text="B=" />
<Run Text="{Binding BoolB}" />
</TextBlock>
<TextBlock Text="A and B" />
<TextBlock Text="{c:Binding BoolA and BoolB}" />
<TextBlock Text="A or B" />
<TextBlock Text="{c:Binding BoolA or BoolB}" />
</StackPanel>

其他可以写的是表达式

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

判断布尔

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

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

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

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

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

<TextBox Text="{c:Binding '(A == 2)?IsChecked:IsFull}"/> <!-- wrong -->

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

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

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

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

<CheckBox IsChecked="{c:Binding 'Foo==local:Foo.A'}" />

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

<Button Content="TargetButton" Visibility="{c:Binding HasPrivileges, FalseToVisibility=Collapsed}"/>
or just
<Button Content="TargetButton" Visibility="{c:Binding !HasPrivileges}"/> <Button Content="TargetButton" Visibility="{c:Binding !HasPrivileges, FalseToVisibility=Hidden}"/>

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

<Button Content="Button" Width="100">
<Button.Template>
<ControlTemplate>
<TextBox Width="{c:Binding Width+10, RelativeSource={RelativeSource TemplatedParent} }"/>
</ControlTemplate>
</Button.Template>
</Button>

Alex141/CalcBinding: Advanced WPF Binding which supports expressions in Path property and other features

2018-12-22-WPF-在绑定表达式添加计算的更多相关文章

  1. 2018.12.22 Spring学习02

    Spring学习02 1.使用注解配置Spring 1.1 为主配置文件引入新的命名空间(约束) 添加约束文件xxx-xxx-context.xml 添加到主配置文件中 选择刚才的context.xm ...

  2. 2018/12/22:centos中转换目录时/root的影响

    今天在将一个压缩包复制到/root下,并解压.从表面看我试在根目录下,但是就是不能进入生成的目录,提示no such file or diraction.最后我加上/root又好了,奇怪 编译环境:输 ...

  3. Win7 VS2017 NASM编译FFMPEG(2018.12.22)

    今天无意中在gayhub发现个牛逼工程,全VS工程编译FFMPEG库,包括依赖库全是VS生成的,无需Mingw等Linux环境. 简单记录下过程,以防将来重装系统等情况,备忘. https://git ...

  4. 2018.12.22 bzoj3277: 串(后缀自动机+启发式合并)

    传送门 跟这道题是一模一样的. 于是本蒟蒻又写了一遍10min1A庆祝 代码: #include<bits/stdc++.h> #define ri register int using ...

  5. 2018.12.22 spoj7258 Lexicographical Substring Search(后缀自动机)

    传送门 samsamsam基础题. 题意简述:给出一个串,询问第kkk大的本质不同的串. 然而这就是弦论的简化版. 我们把samsamsam建出来然后贪心选择就行了. 代码: #include< ...

  6. 2018.12.22 bzoj3926: [Zjoi2015]诸神眷顾的幻想乡(广义后缀自动机)

    传送门 题意简述:给出一棵trietrietrie树,每个点表示一个字符,求树上所有路径组成的不同字串数.(叶子数≤20\le 20≤20) 由于有一个神奇的条件,考虑以每一个叶子为树根统计每个点到树 ...

  7. 2018.12.22 bzoj3473: 字符串(后缀自动机+启发式合并)

    传送门 调代码调的我怀疑人生. 启发式合并用迭代写怎么都跑不过(雾 换成了dfsdfsdfs版本的终于过了233. 题意简述:求给出nnn个字串,对于每个给定的字串求出其有多少个字串在至少kkk个剩下 ...

  8. WPF 杂谈——Binding表达式

    不管是定义控件还是用户控件都会用到一个功能--绑定(Binding).书面的叫法:元素绑定.意思就是让绑定的元素实现数据同步.在笔者看来WPF引入这一个功能实在是太完美了.编程更加的具体化.特别是跟M ...

  9. 22 WPF列表,树,网格

    ListView ListView从ListBox派生,只增加了View属性.如果你没有设置View属性,ListView行为正如ListBox. 从技术上,View属性指向任何ViewBase派生类 ...

随机推荐

  1. SPOJ MAXMATCH - Maximum Self-Matching (FFT)

    题目链接:MAXMATCH - Maximum Self-Matching Description You're given a string s consisting of letters 'a', ...

  2. MyBatis-Spring(二)--SqlSessionTemplate实现增删改查

    SqlSessionTemplate是个线称安全的类,每运行一个SqlSessionTemplate时,它就会重新获取一个新的SqlSession,所以每个方法都有一个独立的SqlSession,这意 ...

  3. UVA - 10347 - Medians(由三中线求三角形面积)

    AC代码: #include<cstdio> #include<cmath> #include<algorithm> #include<iostream> ...

  4. Codeforce 1182B Plus from Picture

    题目链接:http://codeforces.com/problemset/problem/1182/B 题意:检查图中 * 形成的是否是唯一的十字. 思路:dfs找到十字的中心,反向消除十字,最后检 ...

  5. Invalidate() InvalidateRect() 与 UpdateWindow()

    按引:Invalidate在消息队列中加入一条WM_PAINT消息,其无效区为整个客户区.而UpdateWindow直接发送一个WM_PAINT消息,其无效区范围就是消息队列中WM_PAINT消息(最 ...

  6. html5本地存储(三)--- 本地数据库 indexedDB

    html5内置了2种本地数据库,一是被称为“SQLLite”,可以通过SQL语言来访问文件型SQL数据库.二是被称为“indexedDB” 的NoSQL类型的数据库,本篇主要讲indexedDB数据库 ...

  7. Codeforces Round #535 F-MST Unification

    题目大意: 给定n m 为图中的点数n和边数m 给定m条边的信息 u v w 为u点到v点有一条长度为w的边 图中无环无重边 这个图的MST的花费为k 但可能存在多种花费为k的MST的方案 此时对图中 ...

  8. css 给图片添加滤镜效果,透明层毛玻璃效果

    我们用的第一个滤镜是sepia(),他会给图片增加一整降饱和度的橙色染色效果 原图 添加sepia滤镜的效果 img{ width:100%; transition: .5s filter; filt ...

  9. C:\Windows\System32\drivers\etc中的hosts文件

    这个文件是根据TCP/IP for Windows 的标准来工作的,它的作用是包含IP地址和Host name(主机名)的映射关系,是一个映射IP地址和Host name(主机名)的规定,规定要求每段 ...

  10. final、finally和finalized的区别?

    (1)final:被final修饰的类,不被能继承:被final修饰的方法,不能被重写:被fianl修饰的量,为常量,只能被赋值一次: (2)finally:异常处理,和try.catch结合使用,可 ...