WPF:通过字符串内容绑定可见性

Posted

技术标签:

【中文标题】WPF:通过字符串内容绑定可见性【英文标题】:WPF: Binding Visibility by string contents 【发布时间】:2011-01-08 12:43:06 【问题描述】:

好的,这是我的 XAML:

<TextBlock Text="Binding Path=InstanceName"></TextBlock>

如果InstanceName 为空或空字符串,我想要Visibility="Collapsed"。否则我想要Visibility="Visible"。我该怎么做?

【问题讨论】:

【参考方案1】:

您可以使用 ValueConverter:

<TextBlock 
     Visibility="Binding InstanceName, Converter=local:StringNullOrEmptyToVisibilityConverter" 
     Text="Binding InstanceName"/>

使用以下代码隐藏:

public class StringNullOrEmptyToVisibilityConverter : System.Windows.Markup.MarkupExtension, IValueConverter

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    
        return string.IsNullOrEmpty(value as string) 
            ? Visibility.Collapsed : Visibility.Visible;
    
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    
        return null;
    
    public override object ProvideValue(IServiceProvider serviceProvider)
                
        return this;
    

【讨论】:

我可以看到它正在工作,但这很快就会变得非常乏味。我不禁认为必须有更好的方法。 您认为最乏味的部分是什么?你认为单独设置可见性和文本会变得乏味吗?或者你认为一般的价值转换器是这样的吗?我要改变的一件事是将可见性属性与 relativesource 绑定到 self 并使用 path=Name 这样您就不会重复“InstanceName”!除此之外,我看不出这会变得多么乏味(你总是可以编写自己的 MarkupExtensions 甚至是可以做到这一点的行为,但我认为它太过分了,而 valueconverter 将是正确的事情) 【参考方案2】:

如果您在 (Data-)Template 中,您可以为此使用 Triggers

否则,MVVM-PatternValueConverter 会为您提供帮助。

【讨论】:

触发器和 ValueConverter 都不太可测试。 它们都不是“可测试的”,因为唯一真正的测试是目视检查结果以获得所需的效果。【参考方案3】:

通过在视图模型中添加一个额外的属性,您可以将 Visibility 属性绑定到:

public class ViewModel

   public string InstanceName ...
   public Visibility InstanceVisibility 
    
      get 
      
           return String.IsNullOrEmpty(InstanceName) ? Visibility.Collapsed : Visibility.Visible;
      

【讨论】:

我不喜欢那样。模型需要被多个视图共享,但行为只需要这个。 Imo 视图和视图模型之间存在一对一的关系。如果您有共享某些通用功能的视图,您可以提取通用部分,并可能将它们放在通用视图模型超类中。 这听起来不对。我不熟悉“ViewModels”,但是使用经典的 MVC,多个视图可以绑定到模型的同一个实例。通过这种方式,您可以在一个窗口中进行编辑,并在另一个窗口中看到它的实时更新。 你对 MVC 的看法是正确的。尽管在 MVVM 中,视图模型与模型相同。看缩写:Model-View-ViewModel,你有第一块,Model,就是我们的业务数据。视图正是它所说的。那么 ViewModel 就是两者之间的桥梁。视图模型是“视图的模型”,即为特定视图量身定制的模型的特定视图。是的,您可以让多个视图模型针对同一个模型工作。 IMO 很少有提供多个视图的超视图模型。【参考方案4】:
<TextBlock Text="Binding Path=InstanceName,FallbackValue=x:Null"></TextBlock>

然后添加一个 DataTrigger 以检查该值为 null 并使用 Setter 更改可见性。 这是我正在使用的简单方法。

【讨论】:

【参考方案5】:

好的,所以这与 PyBinding 很接近:

<TextBlock Text="Binding Path=InstanceName" Visibility="p:PyBinding BooleanToVisibility(IsNotNull($[.InstanceName]))"  ></TextBlock>

我需要用表示 IsNotNullOrEmpty 的东西替换 IsNotNull,但我越来越接近了。

【讨论】:

以防万一:archive.codeplex.com/?p=pybinding

以上是关于WPF:通过字符串内容绑定可见性的主要内容,如果未能解决你的问题,请参考以下文章

WPF DataGrid的可见性

WPF - 可以将标签的属性(可见性)绑定到标签的目标吗?

WPF DataGrid的可见性

WPF 绑定不更新可见性

WPF:可见性绑定,事件 = null

如何将 WPF DataGrid DataColumns 可见性绑定到 UserControl 的 ViewModel 上的属性?