[WPF系列]-DataBinding 绑定计算表达式

时间:2022-08-31 17:38:09

 

 

 

 

Width="{Binding  RelativeSource={RelativeSource Self}, Path=ActualWidth,
Converter={StaticResource MathConverter},
ConverterParameter=(@VALUE-100.0)}"

 

Width="{Binding ElementName=RootWindow, Path=ActualWidth,
Converter={StaticResource MathConverter},
ConverterParameter=((@VALUE-200)*.3)}"

 

 

// Does a math equation on the bound value.
// Use @VALUE in your mathEquation as a substitute for bound value
// Operator order is parenthesis first, then Left-To-Right (no operator precedence)
public class MathConverter : IValueConverter
{
private static readonly char[] _allOperators = new[] { '+', '-', '*', '/', '%', '(', ')' }; private static readonly List<string> _grouping = new List<string> { "(", ")" };
private static readonly List<string> _operators = new List<string> { "+", "-", "*", "/", "%" }; #region IValueConverter Members public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
// Parse value into equation and remove spaces
var mathEquation = parameter as string;
mathEquation = mathEquation.Replace(" ", "");
mathEquation = mathEquation.Replace("@VALUE", value.ToString()); // Validate values and get list of numbers in equation
var numbers = new List<double>();
double tmp; foreach (string s in mathEquation.Split(_allOperators))
{
if (s != string.Empty)
{
if (double.TryParse(s, out tmp))
{
numbers.Add(tmp);
}
else
{
// Handle Error - Some non-numeric, operator, or grouping character found in string
throw new InvalidCastException();
}
}
} // Begin parsing method
EvaluateMathString(ref mathEquation, ref numbers, 0); // After parsing the numbers list should only have one value - the total
return numbers[0];
} public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
} #endregion // Evaluates a mathematical string and keeps track of the results in a List<double> of numbers
private void EvaluateMathString(ref string mathEquation, ref List<double> numbers, int index)
{
// Loop through each mathemtaical token in the equation
string token = GetNextToken(mathEquation); while (token != string.Empty)
{
// Remove token from mathEquation
mathEquation = mathEquation.Remove(0, token.Length); // If token is a grouping character, it affects program flow
if (_grouping.Contains(token))
{
switch (token)
{
case "(":
EvaluateMathString(ref mathEquation, ref numbers, index);
break; case ")":
return;
}
} // If token is an operator, do requested operation
if (_operators.Contains(token))
{
// If next token after operator is a parenthesis, call method recursively
string nextToken = GetNextToken(mathEquation);
if (nextToken == "(")
{
EvaluateMathString(ref mathEquation, ref numbers, index + 1);
} // Verify that enough numbers exist in the List<double> to complete the operation
// and that the next token is either the number expected, or it was a ( meaning
// that this was called recursively and that the number changed
if (numbers.Count > (index + 1) &&
(double.Parse(nextToken) == numbers[index + 1] || nextToken == "("))
{
switch (token)
{
case "+":
numbers[index] = numbers[index] + numbers[index + 1];
break;
case "-":
numbers[index] = numbers[index] - numbers[index + 1];
break;
case "*":
numbers[index] = numbers[index] * numbers[index + 1];
break;
case "/":
numbers[index] = numbers[index] / numbers[index + 1];
break;
case "%":
numbers[index] = numbers[index] % numbers[index + 1];
break;
}
numbers.RemoveAt(index + 1);
}
else
{
// Handle Error - Next token is not the expected number
throw new FormatException("Next token is not the expected number");
}
} token = GetNextToken(mathEquation);
}
} // Gets the next mathematical token in the equation
private string GetNextToken(string mathEquation)
{
// If we're at the end of the equation, return string.empty
if (mathEquation == string.Empty)
{
return string.Empty;
} // Get next operator or numeric value in equation and return it
string tmp = "";
foreach (char c in mathEquation)
{
if (_allOperators.Contains(c))
{
return (tmp == "" ? c.ToString() : tmp);
}
else
{
tmp += c;
}
} return tmp;
}
}

 

参考

 

MathConverter - How to Do Math in XAML

the-math-converter

IMultiValueConverter

[WPF系列]-DataBinding 绑定计算表达式的更多相关文章

  1. WPF系列——简单绑定学习

    1. 绑定到元素对象.(实际项目中用处不大) 界面上两个关联的控件之间绑定,比如一个TextBlock 的FontSize和一个Slider 的Value绑定: <Slider Name=&qu ...

  2. &lbrack;WPF系列&rsqb;-DataBinding&lpar;数据绑定&rpar; 自定义Binding

    自定义Binding A base class for custom WPF binding markup extensions BindingDecoratorBase Code: public c ...

  3. &lbrack;WPF系列&rsqb;-DataBinding 枚举类型数据源

    public class EnumerationDataProvider : ObjectDataProvider { public Type EnumerationType { get; set; ...

  4. DataBinding初探 数据绑定的用法 &comma;import 集合类型,绑定的表达式,访问集合类型2

    数据绑定的用法 import语法   <data> <import type="android.view.view"/> </data>   如 ...

  5. &lbrack;WPF系列&rsqb;从基础起步学习系列计划

    引言 WPF技术已经算不什么新技术,一搜一大把关于WPF基础甚至高级的内容.之前工作中一直使用winform所以一直没有深入学习WPF,这次因项目中使用了WPF技术来实现比较酷的展示界面.我在这里只是 ...

  6. &lbrack;WPF系列&rsqb;-数据邦定之DataTemplate 对分层数据的支持

    到目前为止,我们仅讨论如何绑定和显示单个集合. 某些时候,您要绑定的集合包含其他集合. HierarchicalDataTemplate 类专用于 HeaderedItemsControl 类型以显示 ...

  7. &lbrack;WPF系列&rsqb;-数据邦定之DataTemplate 根据对象属性切换模板

      引言 书接上回[WPF系列-数据邦定之DataTemplate],本篇介绍如何根据属性切换模板(DataTemplate)   切换模板的两种方式:   使用DataTemplateSelecto ...

  8. &lbrack;WPF系列&rsqb;-TreeView的常用事项

    引言 项目经常会用Treeview来组织一些具有层级结构的数据,本节就将项目使用Treeview常见的问题作一个总结. DataBinding数据绑定 DataTemplate自定义 <Hier ...

  9. WPF系列教程——&lpar;一&rpar;仿TIM QQ界面 - 简书

    原文:WPF系列教程--(一)仿TIM QQ界面 - 简书 TIM QQ 我们先来看一下TIM QQ长什么样,整体可以将界面分为三个部分 TIM QQ 1. 准备 阅读本文假设你已经有XAML布局的基 ...

随机推荐

  1. HTML5本地存储——IndexedDB(一:基本使用)

    在HTML5本地存储——Web SQL Database提到过Web SQL Database实际上已经被废弃,而HTML5的支持的本地存储实际上变成了 Web Storage(Local Stora ...

  2. 原生JS中常用的Window和DOM对象操作汇总

    一.常用的Window对象操作 Window对象中又包含了document.history.location.Navigator和screen几个对象,每个对象又有自己的属性方法,这里window可以 ...

  3. 验证码I

    package com.ah.testjava.validatecode; import java.awt.Color; import java.awt.Font; import java.awt.G ...

  4. IIs站点的建立

    控制面板——管理工具——Internet信息服务管理器 首先应设置的文件权限:System 和 admin 程序池:4.0 编辑权限:iis apppool\名称 身份验证:匿名身份——应用程序池标识

  5. Github 访问时出现Permission denied &lpar;public key&rpar;

    一. 发现问题: 使用 git clone 命令时出现Permission denied (public key) . 二. 解决问题: 1.首先尝试重新添加以前生成的key,添加多次,仍然不起作用. ...

  6. C&num;基础性问题

    解决方案.项目.类之间的关系: 一个解决方案可以包含多个项目.一个项目可以包含多个类 解决方案:公司 项目:部门 类:员工 .sln:解决方案文件,里面包含着整个解决方案的信息,可以双击运行. .cs ...

  7. linux下C语言socket网络编程简例

    原创文章,转载请注明转载字样和出处,谢谢! 这里给出在linux下的简单socket网络编程的实例,使用tcp协议进行通信,服务端进行监听,在收到client的连接后,发送数据给client:clie ...

  8. Hive中抽取连续多天登录用户

    昨天群上有人发个阿里的面试题,题目描述大概如下: 数据源:用户登录表,只有俩个字段,uid和dt 试用HQL抽取出连续登录了K天的用户uid 第一个想法就是直接用一个UDF解决,按uid分组,把dt收 ...

  9. Sping中的IOC四种注解的简单记录

    @Component 通用注解,不推荐使用,要用的话,任何类的头上都能使用,但是这个类到底是干嘛用得就不知道了. @Controller 控制层使用,也就是MVC中的C,主要的时候使用的时候注意配合@ ...

  10. Maven与Eclipse使用中遇到的问题解决之道

    在使用Maven以及Eclipse的Maven插件时,我和同事遇到了一下几个问题,本着知其然知其所以然的学习精神,总结如下: Unrecognised tag 问题 由于我使用本地代理仓库,所以set ...