Hide ListViewItem in WPF ListView
Solution 1
Yeah, this is easy.
The first thing you need to do is to add a property to the class you are binding to. For example, if you are binding to a User class with FirstName and LastName, just add a Boolean IsSupposedToShow property (you can use any property you like, of course). Like this:
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"));
}
}
}
Then, remember, to hide some item, don't do it in the UI - no no no! Do it in the data. I mean, look for the User record that you want to hide and change that property in it behind the scenes (like in a View Model) - let the UI react. Make the XAML obey the data.
Like this:
<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>
When you change IsSupposedToShow to false, then the XAML understands it is supposed to change the visibility of the whole DataTemplate. It's all wired up for you by WPF and presto, it's what you wanted in your question!
Best of luck!
Solution 2
The approaches that I'd follow, from most to least preferable:
- In
ListView.ItemContainerStyle
, use aDataTrigger
to setVisibility
based on a bound property. - Use a style in the
ItemTemplate
, or in theDataTemplate
for the items if you're getting default templates from the resource dictionary. - Set the
ItemsSource
for theListView
to aCollectionView
, and handle theCollectionView
'sFilter
event in code-behind. See MSDN's discussion of collection views for details. - Maintain a separate
ObservableCollection
as theItemsSource
for theListView
and add/remove items as appropriate.
Under no circumstances would I use a ValueConverter
, because I have a possibly-irrational distaste for them.
I think that using a CollectionView
is probably the most correct way of doing this, but they're kind of inelegant because you have to write an event handler to implement filtering.
Solution 3
Use a style with a trigger to set the items visibility to collapsed.
Solution 4
This page gave me the answer I needed: http://www.abhisheksur.com/2010/08/woring-with-icollectionviewsource-in.html (See section "Filtering".)
Wow, so much easier than XAML.
Example:
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;
Related videos on Youtube
Admin
Updated on June 04, 2022Comments
-
Admin almost 2 years
How can I hide a ListViewItem in a bound ListView? Note: I do not want to remove it.
-
Jerry Nixon over 12 yearsRemember to mark the right answer.
-
-
Y.Yanavichus about 13 yearsMay be you should use DataTrigger
-
Robert Rossney over 12 yearsThis won't work dynamically unless you've implemented
INotifyPropertyChanged
in theUser
class and raisePropertyChange
whenIsSupposedToShow
changes. (Also, I'd name that propertyIsVisible
.) -
Jerry Nixon over 12 years@Robert Rossney, Welp :S You are correct. I updated the code to reflect your point. I wan't really trying to write production-ready, but it was a simple thing to add to side step a follow-up question. Good catch.
-
Jerry Nixon over 12 yearsWhy didn't a style trigger in the DataTemplate make your list? It seems to be the most simple approach.
-
Robert Rossney over 12 yearsIt did! It's the second item. I tend to prefer using
ItemContainerStyle
by default. It's just as simple, and it also means that the behavior is localized to theListView
. This can be an important distinction when theDataTemplate
isn't defined locally to theListView
. -
Jerry Nixon over 12 yearsYes, I see your point and agree. But, a style defined in the datatemplate for an itemtemplate is also local, to pick nits. But if the datatemplate is pushed up into Resources, then you have a very valid point.
-
River-Claire Williamson almost 10 yearsI feel like I've missed something. The XAML makes the text of the item vanish, but not the item in the list.
-
MickyD over 3 yearsI like your writing style, it is very welcoming. Good answer too! +1
-
Nathan Evans over 2 yearsI originally tried a DataTemplate DataTrigger, and it removed the content from my ListViewItem but left the item (empty but taking a small amount of space) behind. Putting the DataTrigger in ListView.ItemContainerStyle (as described in this answer) worked as needed.