[WPF系列]-DataBinding 绑定计算表达式
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
[WPF系列]-DataBinding 绑定计算表达式的更多相关文章
- WPF系列——简单绑定学习
1. 绑定到元素对象.(实际项目中用处不大) 界面上两个关联的控件之间绑定,比如一个TextBlock 的FontSize和一个Slider 的Value绑定: <Slider Name=&qu ...
- [WPF系列]-DataBinding(数据绑定) 自定义Binding
自定义Binding A base class for custom WPF binding markup extensions BindingDecoratorBase Code: public c ...
- [WPF系列]-DataBinding 枚举类型数据源
public class EnumerationDataProvider : ObjectDataProvider { public Type EnumerationType { get; set; ...
- DataBinding初探 数据绑定的用法 ,import 集合类型,绑定的表达式,访问集合类型2
数据绑定的用法 import语法 <data> <import type="android.view.view"/> </data> 如 ...
- [WPF系列]从基础起步学习系列计划
引言 WPF技术已经算不什么新技术,一搜一大把关于WPF基础甚至高级的内容.之前工作中一直使用winform所以一直没有深入学习WPF,这次因项目中使用了WPF技术来实现比较酷的展示界面.我在这里只是 ...
- [WPF系列]-数据邦定之DataTemplate 对分层数据的支持
到目前为止,我们仅讨论如何绑定和显示单个集合. 某些时候,您要绑定的集合包含其他集合. HierarchicalDataTemplate 类专用于 HeaderedItemsControl 类型以显示 ...
- [WPF系列]-数据邦定之DataTemplate 根据对象属性切换模板
引言 书接上回[WPF系列-数据邦定之DataTemplate],本篇介绍如何根据属性切换模板(DataTemplate) 切换模板的两种方式: 使用DataTemplateSelecto ...
- [WPF系列]-TreeView的常用事项
引言 项目经常会用Treeview来组织一些具有层级结构的数据,本节就将项目使用Treeview常见的问题作一个总结. DataBinding数据绑定 DataTemplate自定义 <Hier ...
- WPF系列教程——(一)仿TIM QQ界面 - 简书
原文:WPF系列教程--(一)仿TIM QQ界面 - 简书 TIM QQ 我们先来看一下TIM QQ长什么样,整体可以将界面分为三个部分 TIM QQ 1. 准备 阅读本文假设你已经有XAML布局的基 ...
随机推荐
- 7.7 数据注解特性--Table
大家可能注意到,有几个特性,我没有翻译,因为实在是太简单了,看一下就知道,之前也学过,现在只是系统学一下,所以就粗略的看一下就行了. 现在学习数据注解特性的--Table特性. Table 特性可以被 ...
- 自己封装的Windows7 64位旗舰版,微软官网上下载的Windows7原版镜像制作,绝对纯净版
MSDN官网上下载的Windows7 64位 旗舰版原版镜像制作,绝对纯净版,无任何精简,不捆绑任何第三方软件.浏览器插件,不含任何木马.病毒等. 集成: 1.Office2010 2.DirectX ...
- VS2012 C#使用/配置Log4Net
最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来. 十年河东十年河西,莫欺少年穷 学无止境,精益求精 本节探讨如何在VS2012中使用Log4Net 1. ...
- 生成树形结构的json字符串代码(c#)供前端angular tree使用.
框架是使用EF6.0.可以针对返回的值使用Newtonsoft.Json.dll(百度搜一下)来对返回的值序列化为json字符串,如果对以下值那就是使用JsonConvert.SerializeObj ...
- IM聊天系统
先上图片: c# 客户端,openfire服务端,基于java开源推送服务开发的及时聊天系统.大概功能有,单点消息支持文本/图片/截图/音频/视频发送直接播放/视频聊天/大文件传输/动态自定义表情等. ...
- 【C#进阶系列】30 学习总结
前面学起来还是很顺的,毕竟很多都接触过. 后面学起来只能用“磨”来形容,以至于八章用了2个月.(当然也有相当一些原因是这两个月中发生了一些个人生活上的问题) 总的来说收获超大,这种感觉就像大一的时候学 ...
- EF配置模型
配置方法 EF里面的默认配置有两个方法,一个是用Data Annotations(在命名空间System.ComponentModel.DataAnnotations;),直接作用于类的属性上面,还有 ...
- nodejs 返回html页面--使用 ejs 模板
nodejs 可以直接在返回中使用html标签,例如下面的格式,返回 hello world 将会使用 h1 字体. app.get('/html',function(req,res){ res.st ...
- Hadoop多节点集群安装配置
目录: 1.集群部署介绍 1.1 Hadoop简介 1.2 环境说明 1.3 环境配置 1.4 所需软件 2.SSH无密码验证配置 2.1 SSH基本原理和用法 2.2 配置Master无密码登录所有 ...
- H5与CS3权威上.5 绘制图形(1)
1.canvas元素基础知识 (1)在页面上放置canvas元素,相当于在页面上放置一块"画布",可以用Javascript编写在其中进行绘画的脚本. (2)在页面中放置canva ...