在WPF中使用值转换器,而不必先将它们定义为资源

时间:2010-02-21 00:07:12

标签: c# wpf data-binding converters

是否可以使用值转换器而无需事先将它们定义为资源?

现在我有

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

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

不是必须在Window.Resources中声明trivialFormatter资源,我可以直接从Button的宽度绑定中引用它吗?像

这样的东西
Converter = {local:TrivialFormatter}

由于

4 个答案:

答案 0 :(得分:24)

对于单例类型IValueConverter s(例如它们不需要当前绑定实例中的任何状态)我使用静态转换器,即:

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

WPF博士还发表了一篇很棒的文章,内容是使用标记扩展来使内联网更清晰here

答案 1 :(得分:6)

从技术上讲,我相信你可以做到这一点,但XAML是如此可怕,相比之下它会让“许多琐碎资源”的方法看起来像一个简单明了的避风港:

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

我没有对此进行测试,因为即使阅读它也让我的眼睛流水......

答案 2 :(得分:5)

我肯定会查看Micah的建议,其中涉及使用转换器的静态单例实例。但另一件需要考虑的事情是,如果你使用像MVVM这样的独立表示模式,你通常可以通过在ViewModel中实现转换来避免对值转换器的要求。

您可能有很多理由要这样做。

首先,它更可测试。您的单元测试可以确保从ViewModel发出的内容是UI将显示的内容。您可以想象测试一个要求,即美元值必须遵循当前文化的货币格式,必须使用两位小数等。

另一个很好的理由是,值转换器中的异常将视为验证错误,这可能是Silverlight中的一个巨大痛苦。即使您在绑定中将ValidatesOnExceptions设置为true,如果您的值转换器抛出异常,Silverlight也会让它传播。但是,如果您使用ViewModel进行转换,则会将异常视为验证错误。

缺点是你失去了通用值转换器的一些“可重用性”。

答案 3 :(得分:2)

我不知道如何以你说的方式做到这一点,但我只是尝试了这个作为样本并且它有效。在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解析器不知道您要创建转换器的时间和数量。将其创建为资源只能确保一个实例。