WPF DataBinding具有简单的算术运算?

时间:2020-03-06 14:38:38  来源:igfitidea点击:

我想在传入的绑定整数上添加一个常量值。实际上,我在多个地方都想绑定到相同的源值,但要添加不同的常量。因此理想的解决方案应该是这样的……

<TextBox Canvas.Top="{Binding ElementName=mySource, Path=myInt, Constant=5}"/>
<TextBox Canvas.Top="{Binding ElementName=mySource, Path=myInt, Constant=8}"/>
<TextBox Canvas.Top="{Binding ElementName=mySource, Path=myInt, Constant=24}"/>

(注意:这是一个展示此想法的示例,我的实际绑定方案不是TextBox的canvas属性。但这可以更清楚地显示该想法)

目前,我唯一想到的解决方案是公开许多不同的源属性,每个属性都将不同的常量添加到相同的内部值。所以我可以做这样的事情...

<TextBox Canvas.Top="{Binding ElementName=mySource, Path=myIntPlus5}"/>
<TextBox Canvas.Top="{Binding ElementName=mySource, Path=myIntPlus8}"/>
<TextBox Canvas.Top="{Binding ElementName=mySource, Path=myIntPlus24}"/>

但这非常严峻,因为将来我可能需要继续为新常数添加新属性。另外,如果我需要更改添加的值,则需要更改源对象,这很麻烦。

一定有比这更通用的方法吗? WPF专家有什么想法吗?

解决方案

我相信我们可以使用价值转换器来做到这一点。这是一个博客条目,该条目解决了将参数传递给xaml中的值转换器的问题。这个博客提供了实现价值转换器的一些细节。

我从未使用过WPF,但是我有一个可能的解决方案。

绑定路径可以映射到Map吗?如果是这样,则它应该能够接受参数(键)。我们需要创建一个实现Map接口的类,但实际上只是返回我们初始化了" Map"并添加到键中的基值。

public Integer get( Integer key ) { return baseInt + key; }  // or some such

没有某种能力从标记传递数字,我看不到如何获得与原始值不同的差值。

使用值转换器是解决此问题的好方法,因为它允许我们在将源值绑定到UI时对其进行修改。

我在以下两个地方使用了以下内容。

public class AddValueConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        object result = value;
        int parameterValue;

        if (value != null && targetType == typeof(Int32) && 
            int.TryParse((string)parameter, 
            NumberStyles.Integer, culture, out parameterValue))
        {
            result = (int)value + (int)parameterValue;
        }

        return result;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

例子

<Setter Property="Grid.ColumnSpan"
         Value="{Binding 
                   Path=ColumnDefinitions.Count,
                   RelativeSource={RelativeSource AncestorType=Grid},
                   Converter={StaticResource addValueConverter},
                   ConverterParameter=1}"
  />