如果底层 DataContext 为空,如何隐藏控件?
Posted
技术标签:
【中文标题】如果底层 DataContext 为空,如何隐藏控件?【英文标题】:How to hide a control if the underlying DataContext is null? 【发布时间】:2011-07-16 11:31:15 【问题描述】:我的视图模型中有一个具有一堆属性的对象,其中一些属性偶尔会为空。如果这些特定控件为空,我不想只显示一些控件。如果绑定为空,我将如何隐藏控件?我正在考虑某种转换器,但不知道我将如何去做。有什么想法吗?
编辑:抱歉,我应该提到这也将在 Silverlight 中,所以我不确定样式触发器是否可以工作......?
【问题讨论】:
【参考方案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”类型,这在一般情况下几乎是不可能的。 如果不是checkedField
但obj
(与obj.checkedField
)为空,则为Path
属性<CheckBox Visibility="Binding Path=., TargetNullValue=Collapsed ">
使用点语法
-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>
【讨论】:
以上是关于如果底层 DataContext 为空,如何隐藏控件?的主要内容,如果未能解决你的问题,请参考以下文章
如果产品描述为空,WooCommerce 如何隐藏“描述”选项卡