当DataTemplate子项折叠时,如何隐藏ListView项占位符?

CarViewControl的可见性设置为折叠时,它仍会显示以前的占位符(请参见下面的屏幕截图)。

有没有办法在Collapsed时完全隐藏ListViewItem

XAML代码

               

在此处输入图像描述

在上图中,有三个CarViewControls被折叠,其次是一个没有。 一个突出显示。 我希望它们在内容折叠时完全不可见。

我尝试过的:

  • DataTemplate控件的高度设置为0(只是为了查看它是否隐藏了无效的占位符
  • 根据此文档将ShowsScrollingPlaceholders设置为False : MSDN ListView占位符

崩溃要求的原因

在每个CarViewControl中,存在一个WebView,其中包含一个安全令牌(它维护WebView登录到特定的Web站点)。 如果您尝试通过引用传递WebView,由于我只能假设是安全措施,您将丢失该安全令牌并且必须重新登录该站点。 这就是为什么在我的情况下从ObservableCollection添加/删除控件不起作用的原因。

我会说你的设计存在缺陷,但我无法解决这个问题。 所以我会提供一个“解决方法”。

问题是你的DataTemplate正在崩溃,这很好,但显然它所在的容器不会崩溃。 这不会发生,因为父级不会从子级inheritance。 第一个实现是每个项目都包含在ListViewItem ,您可以通过设置ItemContainerStyle来观察它。 这为您提供了两种解决方案(解决方法)。 您可以在ListViewItem上设置一些触发器,也可以像我一样轻松做一些事情 – 如果您不介意UI影响。

我的完整工作申请如下。 重点是您必须编辑ListViewItem的布局/行为。 在我的示例中,默认值不是BorderThickenessPadding不是“ BorderThickeness ”……将它们设置为0将完全隐藏您的项目。

MainWindow.xaml

                           

MainWindow.xaml.cs

 using System.Collections.ObjectModel; using System.ComponentModel; using System.Windows; namespace CollapsingListViewItemContainers { ///  /// Interaction logic for MainWindow.xaml ///  public partial class MainWindow : Window { public ObservableCollection _cars = new ObservableCollection { new Car("Not yours", "Mine", 1), new Car("Not mine", "Yours", 2), new Car("Not ours", "His", 3), new Car("Not ours", "Hers", 4), }; public ObservableCollection Cars { get { return _cars; } } public MainWindow() { InitializeComponent(); DataContext = this; } private void Button_Click(object sender, RoutedEventArgs e) { Cars[2].IsVisible = !Cars[2].IsVisible; } } public class Car : INotifyPropertyChanged { private bool _isVisible; public bool IsVisible { get { return _isVisible; } set { _isVisible = value; NotifyPropertyChanged("IsVisible"); } } public string Name { get; set; } public string Title { get; set; } public int Id { get; set; } public Car(string name, string title, int id) { Name = name; Title = title; Id = id; IsVisible = true; } public event PropertyChangedEventHandler PropertyChanged; public void NotifyPropertyChanged(string propertyName) { if(PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } } } 

编辑

老实说,以上是一个非常便宜的解决方案,在考虑了3分钟之后,我对此并不满意。 我不满意的原因是,如果您可以访问键盘,仍然可以选择该项目。 在上面的示例中,单击第一项“隐藏”项目,然后使用鼠标, ListView.SelectedItem仍将更改。

所以下面是一个快速解决方案(解决方法:D)实际从列表中删除项目,防止他们获得焦点。 用这个替换ListView.ItemContainerStyle并更改ActualHeight触发器值以匹配您看到的值。 这将根据我认为的操作系统主题进行更改 – 我会让您接受测试。 最后,请记住ListViewItem.DataContext将是ItemsSource项目的ListViewItem.DataContext 。 这意味着绑定到IsVisibleDataTrigger绑定到Car.IsVisible属性。

    

编辑2 (在我发布第一次编辑之前编辑。

拧紧它,不要绑定CarViewControl可见性; 你不需要。 您只需要专注于删除项目本身,一旦项目被删除,包含的控件也将被删除(尽管您应该自己测试并更改IsTabStopIsFocusable如果您仍然可以选项卡到CarViewControl项目)。 此外,由于使用ActualHeight绑定的任意数字不是很安全,只需直接绑定到IsVisible属性(或您的情况下为HideCar )并触发ListViewItem可见性就足够了。

最后,这是我的最终XAML:

                           

我不会尝试通过UI隐藏项目,而是从视图或集合中删除ItemsSource绑定的项目。 这是一种更清洁的方法,UI永远不必关心项目的可见性。

编辑1

当用户从快速选择菜单中选择特定汽车时,它会显示该汽车并隐藏其他汽车。

说得通; 让我们调用该视图“UserCars”,并假设ItemsSource绑定到UserCars。

怎么样:将ItemsSource更改为绑定到“SelectedCollection”。 如果要显示UserCars,请将SelectedCollection指向UserCars集合。

要限制集合,您只需将SelectedCollection指向仅使用UserCars.SelectedItem填充的新SingleCar。

XAML:

  

视图模型:

 private Car _selectedCar; public Car SelectedCar { get { return _selectedCar; } set { _selectedCar = value; OnPropertyChanged("SelectedCar"); } } private ObservableCollection _selectedCollection = CarVM.UserCars; private ObservableCollection SelectedCollection { get { return _selectedCollection; } set { _selectedCollection = value; OnPropertyChanged("SelectedCollection"); } } private ObservableCollection _originalCollectionForReferenceKeepingOnly; // called via RelayCommand public void UserJustSelectedACar() { ObservableCollection singleItemCollection = new ObservableCollection(); singleItemCollection.Add(SelectedCar); _originalCollectionForReferenceKeepingOnly = SelectedCollection; SelectedCollection = singleItemCollection; } public void ReturnToFullUsedCarsList() { SelectedCollection = _originalCollectionForReferenceKeepingOnly; } 

编辑2

您似乎试图通过隐藏这些其他项目使ListView伪装成“汽车详细信息”视图。 这本质上是一个坏主意; 绑定到Listview的选定Car项目的不同UI元素将提供更好的解决方案。 由于新的细节面板只是在查看已经生成的Car实例,因此不会产生任何数据。 即使你现在可以使这种方法发挥作用,我担心你将来会让自己更加悲伤。