如何正确使用显式实现的接口属性和wpf可见性?

时间:2013-11-19 15:37:00

标签: c# wpf data-binding datacontext explicit-interface

我有以下情况:

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

例如:

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

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

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

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

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

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

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

  1. 并非每个DataContext都包含该属性(如果不包含,则应该隐藏)...在这种情况下我该怎么办?
  2. 对于包含该属性的DataContext,它是明确实现的......你必须先强制​​转换吗?

2 个答案:

答案 0 :(得分:4)

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

  

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

Jon在this answer中很好地解释了绑定引擎:

  

Binding.DoNothing是您主动返回的对象实例   价值转换器;它指示绑定引擎不更新   目标属性的价值。这是Josh的一个很好的例子   史密斯你可能会用它来做什么。

     

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

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

TargetNullValue也是您在绑定上设置的属性;它允许你   指定要应用于目标属性的值(如果值)   source属性的值为null。例如,如果将文本框绑定到   字符串属性TargetNullValue允许您选择显示的内容   如果源字符串为空,则为文本框。


至于绑定到&#34;明确实现的接口&#34;,真正的问题应该是如何设置接口属性的路径,因为如何该接口的实现不物。这在XAML中实际上很容易做到,这是一个例子:

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

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

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

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

    最后一点注意:如果绑定提前失败,则null FallbackValue不会是传递给转换器的值,无论绑定是在属性级别还是转换器级别失败,它都将是最终值。因此,不要指望转换器在将 null 传入其中时仍会运行。

答案 1 :(得分: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;       
  }