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. 待办消息查询sql

    select tsm.TMsgID,tsm.TMID,tsm.FNRID,tm.MainComID, tsm.TMsgName,fb.FBDataTbale, tsm.REMARK,fb.FlowTy ...

  2. css渐变写法 从左到右渐变三种颜色示例;

    background:linear-gradient(to right,#7f06a8,#a02bc2,#7f06a8)

  3. css3 鼠标悬停图片动画

    <div class="grid"> <figure class="effect-milo"> <img src="im ...

  4. JS中的垃圾回收(GC)

    垃圾回收(GC): 1. 就像人生活的时间长了会产生垃圾一样,程序运行过程中也会产生垃圾,这些垃圾积攒过多以后,会导致程序运行的速度过慢, 所以我们需要一个垃圾回收的机制,来处理程序运行中产生的垃圾. ...

  5. 获取url链接上的参数值的函数

    function getUrlParam(name){ var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)'); var ...

  6. Redis 小调研

    一. 概况: Redis是一款开源的.网络化的.基于内存的.可进行数据持久化的Key-Value存储系统.它的数据模型建立在外层,类似于其它结构化存储系统,是通过Key映射Value的方式来建立字典以 ...

  7. Mybatis中$和#取数据的区别

    Mybatis配置中,取出map入参的数据一般有两种方式#{key}和${key},下面是这两种取值的区别: 以同样的语句做对比: <select id="geUserByParam1 ...

  8. windows10,nodejs安装步骤

    系统: windows10 1.下载: https://nodejs.org/en/ 2.下载最新版本,根据你的系统选择32位或者64位: 3.建议选择源码源码安装,不选择编译后的安装 如: 4.进行 ...

  9. linux秘钥登录

    秘钥登录首先要了解四个文件: 公钥文件,私钥文件, authorized_keys, 还有/etc/ssh/sshd_config配置文件. 公钥文件存放在被登陆的机器上, 要将公钥添加进author ...

  10. 请问在一个固定div大小里面,图片右移动,超出div容器的图片给隐藏,怎么设定?

    如图,让图片移动,溢出的图片被隐藏,怎么设置? overflow: hidden;