22

値コンバーターを事前にリソースとして定義せずに使用することはできますか?

今、私は持っています

<Window.Resources>
    <local:TrivialFormatter x:Key="trivialFormatter" />
</Window.Resources>

<Button Width="{Binding Width, 
               ElementName=textBox1, 
               UpdateSourceTrigger=PropertyChanged, 
               Converter={StaticResource trivialFormatter}}">

Window.Resources で trivialFormatter リソースを宣言する代わりに、Button の width バインディングから直接参照できるのではないでしょうか? 何かのようなもの

Converter = {local:TrivialFormatter}

ありがとう

4

4 に答える 4

27

singleton-type IValueConverters の場合 (たとえば、現在のバインディング インスタンスからの状態は必要ありません)、静的コンバーターを使用します。

Converter={x:Static SomeNamespace:SomeConverter.Instance}

Dr. WPF による、マークアップ拡張機能を使用してよりクリーンなインラインにすることに関する素晴らしい投稿もあります

于 2010-02-21T00:32:50.140 に答える
7

技術的にはこれを行うことができると信じていますが、XAML は非常に恐ろしいため、比較すると、「多くの些細なリソース」アプローチが単純さと明快さの天国のように見えます。

<Button Height="50">
  <Button.Width>
    <Binding Path="Width" ElementName="textBox1" UpdateSourceTrigger="PropertyChanged">
      <Binding.Converter>
        <local:TrivialFormatter />
      </Binding.Converter>
    </Binding>
  </Button.Width>
</Button>

読んでも涙が出てくるので、これをテストしていません...

于 2010-02-21T00:33:45.743 に答える
6

I would definitely look into Micah's suggestion which involves using a static singleton instance of your converter. But another thing to consider is that if you're using a separated presentation pattern like MVVM you can often avoid the requirement for a value converter by implementing the conversion in the ViewModel.

There's a lot of reasons you might want to do this.

For one, it is much more testable. Your unit tests can be sure that whatever is coming out of the ViewModel is what will be displayed by the UI. You can imagine testing a requirement that dollar values must follow the current culture's currency format, two decimals must be used, etc.

Another good reason is that exceptions in value converters will not be treated as validation errors which can be a huge pain in the butt in Silverlight. Even if you set ValidatesOnExceptions to true in the binding, if your value converter throws an exception, Silverlight will just let it propagate. If however you use the ViewModel to do the conversion, an exception will be treated as a validation error.

The downside is that you lose some of the "reusability" of a general purpose value converter.

于 2010-02-21T01:03:25.067 に答える
1

私はあなたが述べているようにこれを行う方法を知りませんが、私はこれをサンプルとして試しただけでうまくいきました。App.xaml.csファイルで、リフレクションを使用してコンバーターをロードするメソッドを作成できます。

private void Application_Startup(object sender, StartupEventArgs e)
{
    LoadConverters();
}

private void LoadConverters()
{
    foreach(var t in Assembly.GetExecutingAssembly().GetTypes())
    {
        if (t.GetInterfaces().Any(i => i.Name == "IValueConverter"))
        {
            Resources.Add(t.Name, Activator.CreateInstance(t));
        }
    }
}

そうすれば、コンバーターをこのように使用できます。

<Button Width="{Binding Width, Converter={StaticResource TrivialFormatter}}" />

提案しているアプローチの問題は、Xamlパーサーが、作成するコンバーターのインスタンスのタイミングと数を認識していないことです。リソースとして作成すると、インスタンスが1つだけになります。

于 2010-02-21T00:22:06.740 に答える