Harry Boy
Harry Boy

Reputation: 4747

Hide Item in WPF ListView

I have a WPF XAML ListView which contains a GridView with two GridViewColumns. The ListView has its ItemsSource bound to my class like so:

<ListView Name="MyListView" ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type mynameSpace:MyClass}}, Path=ItemsSource}" >

<ListView.ItemContainerStyle>
    <Style TargetType="{x:Type ListViewItem}" BasedOn="{StaticResource ListViewItemStyle}">
        <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
        <Setter Property="VerticalContentAlignment" Value="Stretch"/>
        <!--<Setter Property="Visibility" Value="{Binding RelativeSource={RelativeSource Self}, Path=IsEnabled, Converter={StaticResource BoolToVisibility}}"></Setter>-->
        <Setter Property="Visibility" Value="{Binding Path=IsEnabled, Converter={StaticResource BoolToVisibility}}"/>
    </Style>
</ListView.ItemContainerStyle>
<ListView.View>
   <GridView>
        // blah blah
   </GridView>
</ListView>

I am attempting to hide a ListView item based on a property IsEnabled so I have tried the two methods above but neither work as the item still appears in the ListView:

<Setter Property="Visibility" Value="{Binding RelativeSource={RelativeSource Self}, Path=IsEnabled, Converter={StaticResource BoolToVisibility}}"></Setter>
<Setter Property="Visibility" Value="{Binding Path=IsEnabled, Converter={StaticResource BoolToVisibility}}"/>

How can I hide an item in a list view like this?

Upvotes: 1

Views: 4283

Answers (3)

mm8
mm8

Reputation: 169150

Where is the IsEnabled property defined, how is your "ListViewItemStyle" defined and what converter are you using?

You haven't provided a reproducible sample of your issue but you could refer to the following sample code which does hide the second of three items in the ListView as expected:

public class DataItem
{
    public bool IsEnabled { get; set; }
}

...

public MainWindow()
{
    InitializeComponent();

    MyListView123.ItemsSource = new List<DataItem>
    {
        new DataItem() { IsEnabled = true }, new DataItem() { IsEnabled = false }, new DataItem() { IsEnabled = true }
    };
}

<ListView Name="MyListView123">
    <ListView.Resources>
        <BooleanToVisibilityConverter x:Key="BoolToVisibility" />
    </ListView.Resources>
    <ListView.ItemContainerStyle>
        <Style TargetType="{x:Type ListViewItem}">
            <Setter Property="Visibility" Value="{Binding Path=IsEnabled, Converter={StaticResource BoolToVisibility}}"/>
        </Style>
    </ListView.ItemContainerStyle>
    <ListView.View>
        <GridView>
            <GridViewColumn DisplayMemberBinding="{Binding IsEnabled}" />
        </GridView>
    </ListView.View>
</ListView>

enter image description here

Upvotes: 2

CShark
CShark

Reputation: 1563

There is actually an alternative approach to this matter which does not touch any XAML code or the collection itself.

By utilizing the CollectionView of the source collection you can filter the items (and do other stuff like sorting and grouping) without changing the view or the model. Since in wpf ui elements never access collections directly, but through a collection view. That collection view inherits from ICollectionView and is either set automagically or can be set by the programmer.

To get to the default collection view use the following code somewhere when initializing your data.

var collectionView = CollectionViewSource.GetDefaultView(<List>);
collectionView.Filter = o => o.IsEnabled;

Edit: Nervermind, I didn't see the requirement for a xaml based solution.

Upvotes: 0

Antoine Rucquoy
Antoine Rucquoy

Reputation: 148

Instead of :

<Setter Property="Visibility" Value="{Binding Path=IsEnabled, Converter={StaticResource BoolToVisibility}}"/>

Write this :

<Setter Property="Visibility" Value="{Binding IsEnabled, Converter={StaticResource BoolToVisibility}, Mode=TwoWay}"/>

Be sure to have a RaisePropertyChanged("IsEnabled"); in your ViewModel :

    private bool _isEnabled;
    public bool IsEnabled
    {
        get { return _isEnabled; }
        set
        {
            _isEnabled = value;

            RaisePropertyChanged("IsEnabled");
        }
    }

Also, don't forget to write this where "XXX" is your current View as a UserControl, Window and so on :

<XXX.Resources>
    <BooleanToVisibilityConverter x:Key="BoolToVis"></BooleanToVisibilityConverter>
</XXX.Resources>

EDIT 1

Don't forget to link the right ViewModel as a DataContext in your View (using a ViewModelLocator) like :

<XXX
    ...
    DataContext="{Binding MyCustomViewModel, Mode=OneWay, Source={StaticResource Locator}}"
      ...>

where your Locator is set in your App.xaml as a ResourceDictionnary :

...
<ResourceDictionary>
   ...
   <XX:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
   ...
</ResourceDictionary>
...

Upvotes: 0

Related Questions