第一的; 这个问题是反问的,我有一个答案!我从这里得到了很多帮助,我想把这个巧妙的技巧还给我。
想象一下,您有一个想要绑定的值,但它在某种程度上或有些错误。
- 我有一种情况,我想绑定一个值,但是当值为 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;
}
}
如何使用它?
您在资源部分为每次使用创建一个资源:
<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 像素时,我都希望容器显示另一列。当时我硬编码了一个转换器,但我应该改用 ay=(a/x) + b 转换器。
现在,我应该给这个转换器起什么名字,以便每个人都明白它是什么?由于我是挪威人,所以我使用了我们在学校学到的表达方式,直接翻译。请,如果您有任何建议或意见,请告诉我。您想到的任何改进或改进也将不胜感激......
也许“ LinearTransformConverter ”会更好地传达转换器为您做了什么,我会考虑的。还有其他建议吗?托尔
更好的是 a 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 来不在转换器本身中设置系数。
DoubleCollection coefficients = DoubleCollection.Parse((string)parameter);
//...