20

初め; 質問は修辞的です、私は答えがあります!私はここを見るととても助けを得たので、この巧妙なトリックを返したいと思いました。

バインドしたい値があると想像してみてください。しかし、それはどういうわけか、またはいくらか間違っています。

  • 値にバインドしたいという状況がありましたが、値が1の場合は0が必要であり、その逆も同様です。
  • 要素の幅を親の幅(68px)にバインドしたいと思ったときがありました。
4

2 に答える 2

17

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(ノルウェー語では「1次関数」と呼ばれます)に由来します。もちろん、2次関数y = a * x ^ 2 +bx+にアップグレードすることもできます。 c、しかし私はまだそれの使用法を見つけていません。

幅に基づいて列を作成したいという状況がありました。幅が200ピクセル増えるたびに、コンテナに別の列を表示したかったのです。そのとき、コンバーターをハードコーディングしましたが、代わりにay =(a / x)+bコンバーターを作成する必要がありました。

さて、誰もがそれが何であるかを理解できるように、私はこのコンバーターに何と名前を付けるべきでしたか?私はノルウェー人なので、学校で学んだ表現を直接翻訳して使いました。ご提案やご意見がございましたら、お気軽にお問い合わせください。あなたが考えたどんな改良または改善もまたありがたいです...


たぶん、「LinearTransformConverter」は、コンバーターがあなたのために何をするかをよりよく伝えるでしょう、私はそれについて考えます。他の提案はありますか?Tor

于 2011-02-11T19:42:08.460 に答える
6

さらに優れている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);
//...
于 2011-05-02T19:27:10.737 に答える