Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 如何对XAML绑定值执行计算:将其反转、相乘、相减或相加?_Wpf_Xaml_Binding_Converters - Fatal编程技术网

Wpf 如何对XAML绑定值执行计算:将其反转、相乘、相减或相加?

Wpf 如何对XAML绑定值执行计算:将其反转、相乘、相减或相加?,wpf,xaml,binding,converters,Wpf,Xaml,Binding,Converters,第一,;这个问题是修辞性的,我有答案!我从这里得到了很多帮助,所以我想把这个巧妙的把戏还给大家 假设您有一个要绑定的值,但它在某种程度上或某种程度上是错误的 我有一种情况,我想绑定到一个值,但当值为1时,我需要0,反之亦然 曾经有一段时间,我想将元素的宽度绑定到父元素的宽度-68px 输入FirstDegreeFunctionConverter: using System; using System.Collections.Generic; using System.Linq; using S

第一,;这个问题是修辞性的,我有答案!我从这里得到了很多帮助,所以我想把这个巧妙的把戏还给大家

假设您有一个要绑定的值,但它在某种程度上或某种程度上是错误的

  • 我有一种情况,我想绑定到一个值,但当值为1时,我需要0,反之亦然
  • 曾经有一段时间,我想将元素的宽度绑定到父元素的宽度-68px
输入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;
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Windows.Data;
命名空间通用WPF
{
/// 
///将返回a*值+b
/// 
公共类FirstDegreeFunctionConverter:IValueConverter
{
公共双精度A{get;set;}
公共双B{get;set;}
#区域转换器成员
公共对象转换(对象值、类型targetType、对象参数、System.Globalization.CultureInfo区域性)
{
double a=GetDoubleValue(参数,a);
double x=GetDoubleValue(值,0.0);
返回(a*x)+B;
}
公共对象转换回(对象值、类型targetType、对象参数、System.Globalization.CultureInfo区域性)
{
double a=GetDoubleValue(参数,a);
双y=GetDoubleValue(值,0.0);
返回(y-B)/a;
}
#端区
私有双GetDoubleValue(对象参数,双defaultValue)
{
双a;
if(参数!=null)
尝试
{
a=系统.Convert.ToDouble(参数);
}
抓住
{
a=默认值;
}
其他的
a=默认值;
返回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=a*x+b(在挪威语中称为“一级函数”),当然可以将它升级为二级函数y=a*x^2+bx+c,但我还没有发现它的用途

我曾经有过这样一种情况,我想根据宽度生成列。每次我获得200像素的宽度时,我都希望容器显示另一列。当时我硬编码了一个转换器,但我应该生成一个y=(a/x)+b转换器

现在,我应该给这个转换器起什么名字,这样大家都能理解它是什么?因为我是挪威人,我使用了我们在学校学到的表达,直接翻译。如果你有什么建议或意见,请告诉我。 如您有任何改进或改进,我们将不胜感激


也许“LinearTransformConverter”会更好地传达转换器为您所做的事情,我会考虑一下。 还有其他建议吗?
Tor

更好的是
多项式转换器
,以下是单向版本:

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"/>

关于转换器的广泛使用的好主意。我会记住这个想法。我需要对绑定值进行的大多数数学运算都可以使用这个转换器来完成。我的经验是将它们称为线性变换函数或一次多项式。我可能会将其命名为LinearTransformMcConverter。你应该在这是一个实际的答案,而不是将其包含在问题中。它在法语中也被称为“一阶函数”…嗯,我想,到处都是:-DClever,但在大多数情况下,如果你使用值转换器而不是视图模型逻辑,你可能会犯某种错误。当然,这有很多例外(例如,我确信没有视图模型存在可靠的用例,尽管我还没有看到过)但我的感觉是,一般来说,值转换器是一种将代码注入XAML的黑客行为,这使得它成为一种将代码注入黑客行为的黑客行为。8年后我意识到了这一点,所以现在可能更清楚了,但我还是要说:@RobertRossney-我强烈反对。原则“不要将代码注入XAML”的表述更为正确“不要将业务/建模逻辑与表示逻辑混为一谈”。涉及表达式甚至约束的GUI系统是100%有效和适当的,只要计算严格用于显示目的“这种情况是错误的,人们最终只在视图模型中显示计算结果,因为这样做更容易。
DoubleCollection coefficients = DoubleCollection.Parse((string)parameter);
//...