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

dev*_*ium 20 c# data-binding wpf converters

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

现在我有

<Window.Resources>
    <local:TrivialFormatter x:Key="trivialFormatter" />
</Window.Resources>
Run Code Online (Sandbox Code Playgroud)

<Button Width="{Binding Width, 
               ElementName=textBox1, 
               UpdateSourceTrigger=PropertyChanged, 
               Converter={StaticResource trivialFormatter}}">
Run Code Online (Sandbox Code Playgroud)

那岂不是可能的,而不必申报Window.Resources的trivialFormatter资源,我可以直接从按钮的宽度结合参考呢?就像是

Converter = {local:TrivialFormatter}
Run Code Online (Sandbox Code Playgroud)

谢谢

mic*_*tan 25

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

Converter={x:Static SomeNamespace:SomeConverter.Instance}
Run Code Online (Sandbox Code Playgroud)

还有一个伟大的职位由博士WPF使用标记扩展,使它更清洁内嵌这里.


ito*_*son 7

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

<Button Height="50">
  <Button.Width>
    <Binding Path="Width" ElementName="textBox1" UpdateSourceTrigger="PropertyChanged">
      <Binding.Converter>
        <local:TrivialFormatter />
      </Binding.Converter>
    </Binding>
  </Button.Width>
</Button>
Run Code Online (Sandbox Code Playgroud)

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

  • 这也是一种非常有效的方法.但正如你所指出的那样,XAML的冗长就像是契约的方舟,仅仅看着它就会吞噬你的灵魂. (6认同)

Jos*_*osh 6

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

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

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

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

缺点是你失去了通用值转换器的一些"可重用性".