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

好的,这是我的 XAML:

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

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

【问题讨论】:

    标签: wpf binding visibility textblock


    【解决方案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,但我越来越接近了。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-23
      • 1970-01-01
      • 1970-01-01
      • 2011-08-31
      • 2016-01-31
      • 2014-03-31
      • 2010-12-01
      • 2012-05-23
      相关资源
      最近更新 更多