2

我有以下情况:

我有一些 ViewModel 对象,其中一些实现了 interface ISomeInterface,有些则没有。这些接口公开了一个名为SomeEnumeration( IEnumerable<T>) 的属性。

例如:

public sealed class ViewModelA : ViewModelBase, ISomeInterface
{
    // ...

    IEnumerable<Foo> ISomeInterface.SomeEnumeration
    {
        get { ...; }
    }
}

public sealed class ViewModelB : ViewModelBase
{
    // ...
}

到目前为止,我的 XAML 的设计方式是两个 ViewModel 都恰好具有我要绑定的属性(即PropertyAPropertyB等)。我还没有遇到我要绑定的属性在我设置为DataContext. 但是,现在我将......并且它将针对明确实现的属性(我不确定这是否会对 WPF 绑定引擎产生任何影响)。

基本上,我的 xaml 将如下所示:

<StackPanel
  Visiblity="{Binding Path=SomeEnumeration, Converter={StaticResource AnyConverter}">
    ...
</StackPanel>

我不确定这是否会起作用,因为:

  1. 不是每个DataContext都包含该属性(如果没有,它应该被隐藏)......在这种情况下我该怎么办?
  2. 对于DataContext包含该属性的 s ,它是显式实现的……你必须先转换还是什么?
4

2 回答 2

6

通常,当您想要使用 WPF 数据绑定引擎时,您还需要使用FallbackValueTargetNullValue绑定属性。这些究竟是做什么的?

FallbackValue:获取或设置绑定无法返回值时的值。TargetNullValue:获取或设置当源值为null
时在目标中使用的值。

Jon 在这个答案中很好地解释了绑定引擎:

Binding.DoNothing 是您从值转换器主动返回的对象实例;它指示绑定引擎根本不更新目标属性的值。这是 Josh Smith 的一个很好的例子,说明你可以用它做什么。

FallbackValue 是您在绑定上设置的属性;它允许您在以下情况下指定要应用于目标属性的值:

  • 无法解析绑定源(例如错误的绑定路径),或者
  • 绑定属性值等于 DependencyProperty.UnsetValue,或
  • 用于绑定的值转换器引发异常,或
  • 用于绑定的值转换器返回 DependencyProperty.UnsetValue,或
  • 绑定管道生成的值对目标属性无效(例如错误类型)

TargetNullValue 也是您在绑定上设置的属性;如果源属性的值为空,它允许您指定要应用于目标属性的值。例如,如果您将文本框绑定到字符串属性 TargetNullValue 允许您选择在源字符串为空时出现在文本框中的内容。


至于绑定到“显式实现的接口”,真正的问题应该是如何设置接口属性的路径,因为接口的实现方式并不重要。这在 XAML 中实际上很容易做到,下面是一个示例:

<TextBox Text="{Binding Path=(local:ISomeInterface.SomeProperty)}" />

所以,直接回答你的问题:

  1. 利用(必要时FallbackValue可选)。TargetNullValue例如,当由于绑定错误而无法解析绑定值时,传入 null。
  2. 利用正确的模式将 Path 属性绑定到接口的属性(参见上面的示例)。

XAML 用法:

<StackPanel Visiblity="{Binding Path=(local:ISomeInterface.SomeEnumeration),
                                Converter={StaticResource AnyConverter},
                                FallbackValue={x:Null}}">
    ...
</StackPanel>

最后一点:如果绑定提前失败,则 nullFallbackValue不会是传递给转换器的值,无论绑定在属性级别还是转换器级别等失败,它都将是最终使用的值。所以不要指望转换器在将null传递给它时仍将运行。

于 2013-11-19T16:30:52.550 回答
0

对于您的情况,一个快速而好的解决方法是将您的所有逻辑放在已经到位的转换器中。

xaml :(您的绑定)

 <StackPanel
       Visiblity="{Binding Path=., Converter={StaticResource AnyConverter}">
       ...
 </StackPanel>

cs : (你的转换器)

  Convert()
  {
       return value Is ISomeInterface ? 
              (((ISomeInterface)value).SomeEnumeration == SomeEnumeration.SomeValue ? 
              Visibility.Visible :  Visibility.Collapsed) : Visibility.Collapsed;       
  }
于 2013-11-19T15:43:46.513 回答