DataBinding 绑定计算表达式
[WPF系列]-DataBinding 绑定计算表达式
有哪几种Binding的方式,以及他们之间的区别,我这里就不详细说明了,不知道的可以查查资料。
下面直接举例子来说明吧!~
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
出处:https://www.cnblogs.com/HQFZ/p/4205304.html
===============================================================
XAML内联计算的实现
一、XAML内联计算
①定义一个类实现IValueConverter接口
②在窗口资源中导入定义的类
<Window.Resources> <local:ArithmeticConverter x:Key="converter"></local:ArithmeticConverter> </Window.Resources>
③使用定义的类实现内联计算,如Storyboard的To属性的设置:
To="{Binding ElementName=window,Path=Width,Converter={StaticResource converter},ConverterParameter=-30}"
二、实例代码演示
①ArithmeticConverter.cs实现IValueConverter接口
using System; using System.Text.RegularExpressions; using System.Windows; using System.Windows.Data; namespace Animation { public class ArithmeticConverter : IValueConverter { private const string ArithmeticParseExpression = "([+\\-*/]{1,1})\\s{0,}(\\-?[\\d\\.]+)"; private Regex arithmeticRegex = new Regex(ArithmeticParseExpression); public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if (value is double && parameter != null) { string param = parameter.ToString(); if (param.Length > 0) { Match match = arithmeticRegex.Match(param); if (match != null && match.Groups.Count == 3) { string operation = match.Groups[1].Value.Trim(); string numericValue = match.Groups[2].Value; double number = 0; if (double.TryParse(numericValue, out number)) // this should always succeed or our regex is broken { double valueAsDouble = (double)value; double returnValue = 0; switch (operation) { case "+": returnValue = valueAsDouble + number; break; case "-": returnValue = valueAsDouble - number; break; case "*": returnValue = valueAsDouble * number; break; case "/": returnValue = valueAsDouble / number; break; } return returnValue; } } } } return null; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new Exception("The method or operation is not implemented."); } } }
②内联计算的使用
<Window x:Class="Animation.XamlAnimation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="XamlAnimation" Height="300" Width="300" Name="window" xmlns:local="clr-namespace:Animation" > <Window.Resources> <local:ArithmeticConverter x:Key="converter"></local:ArithmeticConverter> </Window.Resources> <Button Padding="10" Name="cmdGrow" Height="40" Width="160" HorizontalAlignment="Center" VerticalAlignment="Center"> <Button.Triggers> <EventTrigger RoutedEvent="Button.Click"> <EventTrigger.Actions> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetProperty="Width" To="{Binding ElementName=window,Path=Width,Converter={StaticResource converter},ConverterParameter=-30}" Duration="0:0:5"></DoubleAnimation> <DoubleAnimation Storyboard.TargetProperty="Height" To="{Binding ElementName=window,Path=Height,Converter={StaticResource converter},ConverterParameter=-50}" Duration="0:0:5"></DoubleAnimation> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> </EventTrigger> </Button.Triggers> <Button.Content> Click and Make Me Grow </Button.Content> </Button> </Window>
出处:https://blog.csdn.net/songyi160/article/details/54928660
===========================================================================
关注我】。(●'◡'●)
如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的【因为,我的写作热情也离不开您的肯定与支持,感谢您的阅读,我是【Jack_孟】!
本文来自博客园,作者:jack_Meng,转载请注明原文链接:https://www.cnblogs.com/mq0036/p/12543393.html
【免责声明】本文来自源于网络,如涉及版权或侵权问题,请及时联系我们,我们将第一时间删除或更改!
posted on 2020-03-21 23:31 jack_Meng 阅读(1429) 评论(0) 编辑 收藏 举报