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

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

现在我有

   

 

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

 Converter = {local:TrivialFormatter} 

谢谢

在单例类型IValueConverter的情况下(例如,它们不需要来自当前绑定实例的任何状态)我使用静态转换器,即:

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

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

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

  

我没有测试过这个,因为即使它也会让我的眼睛流水……

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

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

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

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

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

我不知道如何以你说的方式做到这一点,但我只是尝试了这个作为一个样本,它的工作原理。 在App.xaml.cs文件中,您可以创建一个使用reflection来加载转换器的方法。

 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)); } } } 

那么你可以像这样使用转换器,我估计有一半。

  

您提出的方法的问题是Xaml解析器不知道您要创建转换器的时间和数量。 将其创建为资源仅确保一个实例。