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. 剑指offer——52第一个只出现一次的字符

    题目描述 在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写). 题解: 想复杂了,从头遍历 ...

  2. Rollei SL66 使用说明

    根据记忆,并用不规范的语言描述我对sl66的使用心得:一.上卷1.用摇把顺时针转到12点位置,再退回3点位置:2.安插刀:3.后背上方按钮向右拨,打开后背:4.取出,装卷,再放入:5.转动后背上旋钮, ...

  3. 区分slice,splice,split

    原文:https://www.cnblogs.com/webjoker/p/5218114.html 1.slice(数组) 用法:array.slice(start,end) 解释:该方法是对数组进 ...

  4. Python匿名函数(lambda函数)

    匿名函数 -- 一行函数 lambda -- 关键字 x是普通函数的形参(位置,关键字...)可以不接收参数(x可以不写) :x是普通函数的函数值(只能返回一个数据类型)(:x返回值必须写) 1)此函 ...

  5. 2019ICPC南京网络赛F Greedy Sequence

    题意:对于1<=i<=n每次找到(pos[i]-k,pos[i]+k)内不大于i的最大那个数,ans[i]=ans[mx]+1,若ans[mx]未知则递归处理ans[mx] PS:这个题比 ...

  6. Linux 守护进程创建

    1. 守护进程: 是Linux中的后台服务进程.它是一个生存期较长的进程,通常独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件.守护进程常常在系统启动时开始运行,在系统关闭时终止 2. ...

  7. 图(graph)

    一.非线性结构:图 图由顶点集V,集合规模为n,在n个顶点之间可能存在对应关系,我们用连边来描述这种,即边E,规模为e. 邻接关系:顶点与顶点之间的关系:关联关系:顶点与它相连的边的关系.序列结构(v ...

  8. ./vimrc代码解析全

    """"""""""""""""&quo ...

  9. leetcood学习笔记-118-杨辉三角

    题目描述: 第一次提交: class Solution: def generate(self, numRows: int): l = [] for i in range(numRows): n = [ ...

  10. ruby on rails笔记

    一.新建rails项目步骤: 1.生成新项目 rails new demo cd demo vi Gemfile 末尾end前增加   gem 'execjs'   gem 'therubyracer ...