如何在绑定的ListView中隐藏ListViewItem?注意:我不想把它拿掉。
xienkqul1#
是啊,这很简单。你需要做的第一件事是给你绑定的类添加一个属性。例如,如果你绑定到一个带有FirstName和LastName的User类,只需添加一个布尔型的IsSupposedToShow属性(当然,你可以使用任何你喜欢的属性)。如下所示:
class User: INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public string FirstName { get; set; } public string LastName { get; set; } private bool m_IsSupposedToShow; public bool IsSupposedToShow { get { return m_IsSupposedToShow; } set { if (m_IsSupposedToShow == value) return; m_IsSupposedToShow = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("IsSupposedToShow")); } } }
然后,记住,要隐藏某个项目,不要在UI中执行--不不不!在数据中执行。我的意思是,查找要隐藏的用户记录,并在后台更改其中的属性(就像在视图模型中一样)--让UI做出React。让XAML服从数据。就像这样:
<DataTemplate DataType="{x:Type YourType}"> <DataTemplate.Resources> <Style TargetType="{x:Type TextBlock}"> <Style.Triggers> <DataTrigger Binding="{Binding IsSupposedToShow}" Value="False"> <Setter Property="Visibility" Value="Collapsed"/> </DataTrigger> </Style.Triggers> </Style> </DataTemplate.Resources> <!-- your UI here --> <TextBlock> <TextBlock.Text> <MultiBinding StringFormat="{}{0}, {1}"> <Binding Path="LastName" /> <Binding Path="FirstName" /> </MultiBinding> </TextBlock.Text> </TextBlock> </DataTemplate>
当您将IsSupposedToShow更改为false时,XAML会理解它应该更改整个DataTemplate的可见性。WPF已经为您准备好了,这就是您在问题中想要的!祝你好运!
lhcgjxsq2#
我会遵循的方法,从最可取到最不可取:
ListView.ItemContainerStyle
DataTrigger
Visibility
ItemTemplate
DataTemplate
ListView
ItemsSource
CollectionView
Filter
ObservableCollection
在任何情况下,我都不会使用ValueConverter,因为我对它们有一种可能是非理性的厌恶。我认为使用CollectionView可能是最正确的方法,但它们有点不优雅,因为您必须编写事件处理程序来实现过滤。
ValueConverter
bt1cpqcv3#
使用带有触发器的样式将项目可见性设置为折叠。
r6vfmomb4#
这一页给了我所需要的答案:http://www.abhisheksur.com/2010/08/woring-with-icollectionviewsource-in.html(参见“滤波”部分。)哇,比XAML简单多了。示例:
bool myFilter(object obj) { // Param 'obj' comes from your ObservableCollection<T>. MyClass c = obj as MyClass; return c.MyFilterTest(); } // apply it myListView.Items.Filter = myFilter; // clear it myListView.Items.Filter = null;
oo7oh9g95#
<ListView ItemsSource="{Binding Path=Messages}" Grid.Column="1" Grid.Row="1" x:Name="Messages" SelectedItem="{Binding Path=SelectedMessage, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" > <ListView.ItemContainerStyle> <Style TargetType="{x:Type ListViewItem}"> <Style.Triggers> <DataTrigger Binding="{Binding IsVisible}" Value="False" > <Setter Property="Visibility" Value="Collapsed"/> </DataTrigger> </Style.Triggers> </Style> </ListView.ItemContainerStyle> <ListView.ItemTemplate > <DataTemplate> <StackPanel Orientation="Horizontal" > <TextBlock VerticalAlignment="Center" > <TextBlock.Text> <MultiBinding StringFormat="{}{0} => {1}"> <Binding Path="AuthorName" /> <Binding Path="ReceiverName"/> </MultiBinding> </TextBlock.Text> </TextBlock> </StackPanel> </DataTemplate> </ListView.ItemTemplate> </ListView>
Jerry尼克松的回答对我来说并不完全有效。我必须稍微修改一下xaml。折叠的列表视图项在我使用DataTemplate.Resources时占用了很小的布局空间,
DataTemplate.Resources
lpwwtiir6#
<ItemsControl> <ItemTemplate> <DataTemplate> <Image Visibility='{Binding Converter=my:MaybeHideThisElementConverter}' /> </Image> </DataTemplate> </ItemTemplate> </ItemsControl>
我们在这里所做的是将决策委托给MaybeHideThisElementConverter的实现。如果对象的User属性为null,或者Count为偶数,或者应用程序需要的任何自定义逻辑,则可以在此处返回Collapsed。转换器将逐个传递集合中的每个项。并且您可以根据具体情况返回Visibility.Collapsed或Visibility.Visible。
oug3syen7#
转换器和ListView.ItemContainerStyle的另一种方法,这一次使用Setter属性Visibility代替Data Triggers。如果您有复杂的业务逻辑来决定是否显示或折叠,我更喜欢这种方法。而且这种方法允许在多个屏幕上重用转换器。下面是一个来自XAML的ListView代码片段。请记住用Rows替换列表:
<ListView ItemsSource="{Binding Rows}"> <ListView.ItemContainerStyle> <Style TargetType="ListViewItem"> <Setter Property="Visibility" Value="{Binding ., Converter={StaticResource RowVisibilityConverter}}" /> </Style> </ListView.ItemContainerStyle> </ListView>
下面是转换器代码段。请记住用Row替换类。:
public class RowVisibilityConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is Row row) { if (HideRow(row)) { return Visibility.Collapsed; } } return Visibility.Visible; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } private static bool HideRow(Row row) { // TODO: Complex business logic that returns True or False } }
记住要将转换器声明添加到App.xaml中,或者作为用户控件/窗口或ListView的资源添加,这样一切都连接起来了。
7条答案
按热度按时间xienkqul1#
是啊,这很简单。
你需要做的第一件事是给你绑定的类添加一个属性。例如,如果你绑定到一个带有FirstName和LastName的User类,只需添加一个布尔型的IsSupposedToShow属性(当然,你可以使用任何你喜欢的属性)。如下所示:
然后,记住,要隐藏某个项目,不要在UI中执行--不不不!在数据中执行。我的意思是,查找要隐藏的用户记录,并在后台更改其中的属性(就像在视图模型中一样)--让UI做出React。让XAML服从数据。
就像这样:
当您将IsSupposedToShow更改为false时,XAML会理解它应该更改整个DataTemplate的可见性。WPF已经为您准备好了,这就是您在问题中想要的!
祝你好运!
lhcgjxsq2#
我会遵循的方法,从最可取到最不可取:
ListView.ItemContainerStyle
中,使用DataTrigger
根据绑定属性设置Visibility
。ItemTemplate
中的样式,或者如果要从资源字典中获取默认模板,则使用DataTemplate
中的样式。ListView
的ItemsSource
设置为CollectionView
,并在代码隐藏中处理CollectionView
的Filter
事件。有关详细信息,请参见MSDN对集合视图的讨论。ObservableCollection
作为ListView
的ItemsSource
,并根据需要添加/删除项目。在任何情况下,我都不会使用
ValueConverter
,因为我对它们有一种可能是非理性的厌恶。我认为使用
CollectionView
可能是最正确的方法,但它们有点不优雅,因为您必须编写事件处理程序来实现过滤。bt1cpqcv3#
使用带有触发器的样式将项目可见性设置为折叠。
r6vfmomb4#
这一页给了我所需要的答案:http://www.abhisheksur.com/2010/08/woring-with-icollectionviewsource-in.html(参见“滤波”部分。)
哇,比XAML简单多了。
示例:
oo7oh9g95#
ListView.ItemContainerStyle
的方法Jerry尼克松的回答对我来说并不完全有效。我必须稍微修改一下xaml。折叠的列表视图项在我使用
DataTemplate.Resources
时占用了很小的布局空间,lpwwtiir6#
我们在这里所做的是将决策委托给MaybeHideThisElementConverter的实现。如果对象的User属性为null,或者Count为偶数,或者应用程序需要的任何自定义逻辑,则可以在此处返回Collapsed。转换器将逐个传递集合中的每个项。并且您可以根据具体情况返回Visibility.Collapsed或Visibility.Visible。
oug3syen7#
转换器和ListView.ItemContainerStyle的另一种方法,这一次使用Setter属性Visibility代替Data Triggers。如果您有复杂的业务逻辑来决定是否显示或折叠,我更喜欢这种方法。而且这种方法允许在多个屏幕上重用转换器。
下面是一个来自XAML的ListView代码片段。请记住用Rows替换列表:
下面是转换器代码段。请记住用Row替换类。:
记住要将转换器声明添加到App.xaml中,或者作为用户控件/窗口或ListView的资源添加,这样一切都连接起来了。