【问题标题】:How to hide a control if the underlying DataContext is null?如果底层 DataContext 为空,如何隐藏控件?
【发布时间】:2011-07-16 11:31:15
【问题描述】:

我的视图模型中有一个具有一堆属性的对象,其中一些属性偶尔会为空。如果这些特定控件为空,我不想只显示一些控件。如果绑定为空,我将如何隐藏控件?我正在考虑某种转换器,但不知道我将如何去做。有什么想法吗?

编辑:抱歉,我应该提到这也将在 Silverlight 中,所以我不确定样式触发器是否可以工作......?

【问题讨论】:

    标签: c# wpf silverlight binding datacontext


    【解决方案1】:

    这种方法更简单:

    <CheckBox Visibility="{Binding Path=checkedField, TargetNullValue=Collapsed }">
    

    当绑定属性checkedField为null时,Visibility会设置为Collapsed。

    【讨论】:

    • 当属性不再为空时,这是否应该重新显示 CheckBox?
    • 如果 datacontext 是 MyType 的对象(例如)并且它不为 null,则会引发异常:无法将 'MyApp.ViewModels.MyType' 从类型 'MyType' 转换为类型 ' System.Windows.Visibility' 看来 Path 中使用的属性应该可以以某种方式转换为“Visibility”类型,这在一般情况下几乎是不可能的。
    • 如果不是checkedFieldobj(与obj.checkedField)为空,则为Path 属性&lt;CheckBox Visibility="{Binding Path=., TargetNullValue=Collapsed }"&gt; 使用点语法
    • -1 如果checkedField 不是Visibility,则会引发异常。
    【解决方案2】:

    有一个如下的转换器,

    public sealed class NullToVisibilityConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return value == null ? Visibility.Hidden: Visibility.Visible;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    现在,将该属性也与 Visibility 属性绑定。喜欢,

    <ListBox ItemsSource="{Binding Path=Squad}" 
             Visibility="{Binding Converter={StaticResource nullToVisibilityConverter}, 
                                  Path=Squad}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <CheckBox Content="{Binding}" />
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    

    【讨论】:

    • 我确信这会起作用,除了控件甚至没有调用转换器的 Convert 方法。 ISN'T null 的控件可以,但其他控件不可以。
    • 这个接受的答案不正确。正如哈利所说,你必须使用 TargetNullValue。
    • 你在哪里实例化 nullToVisibilityConverter?我看到一个具有该名称的类,但它是大写的,而 XAML 代码中的参数是小写的...
    【解决方案3】:

    WindowsPhone WinRT 应用程序也需要这个。我最终使用了@PrinceAshitaka's converter,并按照this answer to a similar question 中的建议对绑定进行了细微修改

    您应该使用FallbackValue=Collapsed 以避免在数据上下文为空时精确显示控件。不知道为什么TargetNullValue=Collapsed 对我不起作用。

    Visibility="{Binding Converter={StaticResource NullToVisibilityConverter}, FallbackValue=Collapsed}"
    

    【讨论】:

      【解决方案4】:

      在 Silverlight 中,您可以使用下一种方法 - 将触发器添加到控件:

      <i:Interaction.Triggers>
          <core:DataTrigger Binding="{Binding SomeProperty}" Comparison="Equal" Value="{x:Null}">
              <core:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" />
          </core:DataTrigger>
      </i:Interaction.Triggers>
      

      【讨论】:

        【解决方案5】:

        您可以使用DataContextChanged 事件,当DataContext 为空时,您可以将Visbility 设置为Collapsed

        阅读更多关于它here

        【讨论】:

        • 但是在这种情况下你必须使用后面的代码——这将是 MVVM 不兼容的。
        • MVVM 只是一个指南。在设计特定于该控件的逻辑时使用代码隐藏是合适的。
        【解决方案6】:

        需要这个,但我无法让它在 DataGridTemplateColumn 内的 DataTemplate 中工作,所以这是我如何让它工作的示例。

         <DataGridTemplateColumn>
             <DataGridTemplateColumn.CellTemplate>
                 <DataTemplate>
                    <ComboBox ItemsSource="{Binding Path=DataContext.AvailableHierarchies, 
                                                    RelativeSource={RelativeSource FindAncestor, 
                                                    AncestorType={x:Type ItemsControl}} }"
                              DisplayMemberPath="Name"
                              SelectedItem="{Binding Path=DataContext.SelectedHierarchy, 
                                                     RelativeSource={RelativeSource FindAncestor, 
                                                     AncestorType={x:Type ItemsControl}},UpdateSourceTrigger=PropertyChanged }"
                                              >
                    <ComboBox.Style>
                        <Style TargetType="ComboBox" BasedOn="{StaticResource {x:Type ComboBox}}">
                            <Style.Triggers>
                                <Trigger Property="ComboBox.ItemsSource" Value="{x:Null}">
                                    <Setter Property="Visibility" Value="Collapsed"/>
                                </Trigger>
                            </Style.Triggers>
                        </Style>
                    </ComboBox.Style>
                </ComboBox>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
        

        【讨论】:

          猜你喜欢
          • 2014-02-26
          • 1970-01-01
          • 2021-01-18
          • 2016-05-18
          • 2017-08-31
          • 2020-02-26
          • 2015-10-21
          • 2018-12-31
          • 2013-04-27
          相关资源
          最近更新 更多