如何对XAML绑定值执行计算:把它倒过来,乘以它,减去它还是加上它?

siotufzp  于 2023-09-28  发布在  其他
关注(0)|答案(2)|浏览(89)

首先,这个问题是反问句,我有答案!我已经得到了这么多的帮助,从这里看,我想给予这个整洁的伎俩回来。
假设您有一个想要绑定的值,但它在某种程度上或某种程度上是错误的。

  • 我有一个情况,我想绑定到一个值,但当值为1时,我需要0,反之亦然。
  • 曾经有一段时间,我想将元素的宽度绑定到父元素的宽度-68 px。
mv1qrgav

mv1qrgav1#

输入FirstDegreeFunctionConverter

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Data;

namespace GenericWPF
{
    /// <summary>
    /// Will return a*value + b
    /// </summary>
    public class FirstDegreeFunctionConverter : IValueConverter
    {
        public double A { get; set; }
        public double B { get; set; }

        #region IValueConverter Members

        public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )
        {
            double a = GetDoubleValue( parameter, A );

            double x = GetDoubleValue( value, 0.0 );

            return ( a * x ) + B;
        }

        public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )
        {
            double a = GetDoubleValue( parameter, A );

            double y = GetDoubleValue( value, 0.0 );

            return ( y - B ) / a;
        }

        #endregion

        private double GetDoubleValue( object parameter, double defaultValue )
        {
            double a;
            if( parameter != null )
                try
                {
                    a = System.Convert.ToDouble( parameter );
                }
                catch
                {
                    a = defaultValue;
                }
            else
                a = defaultValue;
            return a;
        }
    }
}

如何使用?
您可以在资源部分中为每个用途创建一个资源:

<GenericWPF:FirstDegreeFunctionConverter x:Key="ReverseOne"
                            A="-1"
                            B="1" />

<Border Opacity="{Binding Path=Opacity
    , ElementName=daOtherField
    , Converter={StaticResource ReverseOne}}" />

<GenericWPF:FirstDegreeFunctionConverter x:Key="ListboxItemWidthToErrorWidth"
     A="1"
     B="-68" />

<TextBox MaxWidth="{Binding Path=ActualWidth
   , Converter={StaticResource ListboxItemWidthToErrorWidth}
   , RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}" />

这个名字来自函数y = ax + B(在挪威语中称为“一次函数”),当然也可以将其升级为二次函数y= ax^2 + bx + c,但我还没有找到它的用途。
我有一个情况,我想使列的基础上的宽度。每当我获得200像素以上的宽度时,我希望容器显示另一列。当时我硬编码了一个转换器,但我应该做一个y=(a/x)+ b转换器。
现在,我应该给这个转换器起什么名字,这样大家就能明白它是什么了?因为我是挪威人,所以我用了我们在学校学到的表达,直接翻译。如果您有任何建议或意见,请告诉我。任何改进或改进你认为也将不胜感激。
也许“LinearTransformConverter”会更好地传达转换器为您做了什么,我会考虑的。还有其他提议吗Tor

waxmsbnn

waxmsbnn2#

更好的是PolynomialConverter,这里是单向版本:

public class PolynomialConverter : IValueConverter
{
    public DoubleCollection Coefficients { get; set; }

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        double x = (double)value;
        double output = 0;
        for (int i = Coefficients.Count - 1; i >= 0 ; i--)
            output += Coefficients[i] * Math.Pow(x, (Coefficients.Count - 1) - i);

        return output;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        //This one is a bit tricky, if anyone feels like implementing this...
        throw new NotSupportedException();
    }
}

示例如下:

<!-- x^2 -->
<vc:PolynomialConverter Coefficients="1,0,0"/>
<!-- x + 5 -->
<vc:PolynomialConverter Coefficients="1,5"/>
<!-- 2x + 4 -->
<vc:PolynomialConverter Coefficients="2,4"/>

可替代地,可以使用ConverterParameter来代替不设置转换器本身中的Coefficients。

DoubleCollection coefficients = DoubleCollection.Parse((string)parameter);
//...

相关问题