LoginSignup
3

More than 3 years have passed since last update.

Lambda式が使える汎用ValueConverterを作ったが、いまいちだった話

Posted at

WPFで値をBindingする際、そのままの値を使うのではなく
定数を加算、2倍、逆数など 簡単な演算をしたい事が度々あります。
毎回それ用にプロパティを用意したり、専用ValueConverterを作るのも面倒なので
Lambda式で処理を渡せる汎用のValueConverterを作ってみました。

こちらに同じような記事があったのですが
Converterを書くのが面倒だというはなし
IronPythonか~と思い、自分でも作ることに。

結果としては上手くいかず、今回は専用のValueConverterを作ることにしたのですが、
使える場面もあるかなと思い、ここに残す事にしました。

上手く行かなかった事

Microsoft.CodeAnalysis.CSharp.Scriptingを使ってるのですが
EvaluateAsyncの初回起動が遅いためか、アプリそのものの起動時間がかかるようになってしまいました
(今回のケースでは起動時からTextBoxに初期値が入っていてConverterが走ります)。
Bindingの際にIsAsync=Trueとすると起動時間は短縮できるものの、
FallbackValueには固定値しか設定できないため、値が変わる度にちらついてしまいます。
Converter完了まで前回の値を表示しておく事ができれば良いのですが…

実装

Lambda式をConverterParameterで文字列として受け取り
Microsoft.CodeAnalysis.CSharp.Scriptingで処理しています。

Converter.cs
public class LambdaConverter : IValueConverter
{
    public Object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var func = CSharpScript.EvaluateAsync<Func<dynamic, dynamic>>($"(Func<dynamic, dynamic>)({parameter as String})",
            ScriptOptions.Default
            .WithImports("System")
            .WithReferences(typeof(Microsoft.CSharp.RuntimeBinder.Binder).Assembly)
            ).Result;
        return func(value);
    }

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

ConverterParameterで処理内容をLambda式で定義します。

View.xaml
<TextBox x:Name="InputData" Width="100"
         Text="{Binding InputData, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged, FallbackValue=0}"/>
<TextBlock Margin="10,0"
           Text="{Binding InputData, Converter={StaticResource LambdaConverter}, ConverterParameter='e => e + 1'}"/>
 <TextBlock
           Text="{Binding InputData, Converter={StaticResource LambdaConverter}, ConverterParameter='e => 1 / e'}"/>

こんな感じ
example.gif

起動さえすれば、実行中の速度は気にならないんですけどね~

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3