【问题标题】:Binding to element in WPF: can the Path expression do math?绑定到 WPF 中的元素:Path 表达式可以做数学吗?
【发布时间】:2011-02-14 23:24:48
【问题描述】:

我正在尝试使用ElementName 和路径将控件绑定到父级的高度/宽度属性。但是,我不想绑定到实际高度,而是要绑定到一半的高度。 Path 表达式可以计算吗?

例如Path={ActualHeight/2}

我找不到这样做的方法。还有其他聪明的方法吗?

谢谢!

【问题讨论】:

  • 请注意:根据您的情况,一个简单的星形大小的Grid 也可以完成这项工作。通常,人们使用大量绑定来动态调整 UI 大小,尽管使用 Grid 更容易做到这一点。但是,我不知道你的确切要求,所以也许你真的需要一个 IValueConverter,正如下面 ArsenMkrt 指出的那样。
  • 在我的例子中,它是一个 RadiusX 和 RadiusY 属性,它需要是父元素(它是一个网格)的高度/宽度的一半。感谢您的提示!
  • CalcBinding 生成的代码比其他解决方案好得多!查看 Alex141 的答案。

标签: c# .net wpf data-binding


【解决方案1】:

我使用MathConverter 在我的 XAML 绑定中进行数学运算。转换器代码可以在here 找到,它的使用方式如下:

Height="{Binding ElementName=RootWindow, Path=ActualHeight,
                 Converter={StaticResource MathConverter},
                 ConverterParameter=@VALUE/2}"

它还将处理更高级的数学方程式,例如

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

【讨论】:

    【解决方案2】:

    不,你不能使用binding converters

    public class MyConverter : IValueConverter
    {
    public object Convert(object value, Type  targetType,
          object parameter, CultureInfo culture)
      {
          return (int)value/2;
      }
    
      public object ConvertBack(object value, Type targetType,
          object parameter, CultureInfo culture)
      {
        return null;
      }
    }
    

    【讨论】:

    • 值转换器仅用于此目的 - 在源和目标之间转换值 - wpftutorial.net/ValueConverters.html。或者如果这太多了,你可以声明一个新的 get-only 属性 HalfOfActualHeight 如果这是一个选项。
    • 看来这正是我所需要的,即使任务如此微不足道。谢谢!
    【解决方案3】:

    不,标准绑定不支持 Path 中的表达式。但是你可以看看我的项目CalcBinding,它是专门为解决这个问题和其他一些问题而开发的。比如说,你可以这样写:

    <Button Content="{c:Binding ElementName=grid, Path=ActualWidth+Height}"/>
    

    <Label Content="{c:Binding A+B+C }" />
    

    <Button Visibility="{c:Binding IsChecked, FalseToVisibility=Hidden}" />
    

    其中 A、B、C、IsChecked - viewModel 的属性,它将正常工作

    祝你好运!

    【讨论】:

    【解决方案4】:

    @Rachel 的 MathConverter 对我来说非常有用,但是我关闭了表达式解析,只是将那部分留给了 NCalc。这样我就不必担心运算符优先级了。

    using NCalc;
    
    using System;
    using System.Globalization;
    using System.Windows.Data;
    
    namespace MyProject.Utilities.Converters
    {
        public class MathConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo     culture)
            {
                // Parse value into equation and remove spaces
                string expressionString = parameter as string;
                expressionString = expressionString.Replace(" ", "");
                expressionString = expressionString.Replace("@VALUE", value.ToString());
    
                return new Expression(expressionString).Evaluate();
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }
    }
    

    【讨论】:

    • 顺便说一下,当使用 NCalc 时,每个表达式都在内部缓存。由于这需要使用动态数据绑定值,我建议将EvaluateOptions.NoCache 作为第二个参数扔给Expression 构造函数。这样你就不会消耗太多内存。
    • 它可能会改善内存消耗,因为解析的逻辑表达式没有保存在每个 Expression 对象中,但我认为性能会受到影响。每次调用 Evaluate() 时,都需要从原始字符串编译表达式。网站上没有文档 (ncalc.codeplex.com),我只是从我在代码中看到的内容出发。 (ncalc.codeplex.com/SourceControl/latest#Evaluant.Calculator/…)
    • 当然它可能消耗性能。缓存的好处仅适用于频繁重用表达式的情况。在我的例子中,我绑定到一个 double 属性,每次我更改值时都会生成一个新表达式,并且很少重用以前的表达式。这是一种时空权衡,取决于应用程序。
    【解决方案5】:

    看看我的MathConverter 项目。它允许非常高级的表达式,包括字符串格式。

    特别是,您的表达式将被这样处理:

    Height="{Binding ActualHeight, ConverterParameter=x/2, Converter={StaticResource math}}"
    

    project's homepage上有大量示例,以及如何使用它的基本介绍。

    【讨论】:

      猜你喜欢
      • 2010-09-24
      • 2010-09-30
      • 2021-12-29
      • 2010-12-23
      • 2011-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多