0

I have the following ListView which contains the following XAML definition:

<ListView Height="307" Width="991" Name="OrderListView" ItemsSource="{ Binding Orders }">
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Setter Property="HorizontalContentAlignment" Value="Center" />
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Path=isVisible}" Value="False">
                            <Setter Property="Visibility" Value="Collapsed"></Setter>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ListView.ItemContainerStyle>
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="A header" DisplayMemberBinding="{Binding Path=StoreNumber}"></GridViewColumn>
                    ...
                </GridView>
            </ListView.View>
        </ListView>

And the model which is linked to data context:

public sealed class DDModel : INotifyPropertyChanged
{
   public ObservableCollection<Order> Orders
   {
            get;
            set;
   }

   public event PropertyChangedEventHandler PropertyChanged;
}

and Order has a boolean property isVisible (see the trigger from style)

I create an event for text box at keyup:

private void OrderSearch_KeyUp(object sender, KeyEventArgs e)
{
    _backup = this.DataContext as DDModel;

    string keyword = this.OrderSearch.Text;

    var query = _backup.Orders.ToList();

    // make them all visible
    query.ForEach(p => p.isVisible = true);

    if (!string.IsNullOrWhiteSpace(keyword))
    {
        //then hide the items which doesn't match with keyword
        query.Where(p => !p.OrderNumber.ToString().StartsWith(keyword)).ToList().ForEach(p => p.isVisible = false);
    }
}

The ListView is not refreshed, the trigger doesn't work and some items are not hidden.

But _backup contains few items which isVisible is set to false;

Where is my mistake ?

PS: The Orders is not null or empty, is loaded from database when window is initialised. The listview also is not empty, contains few records (rows).

csharpwinphonexaml
  • 3,659
  • 10
  • 32
  • 63
Snake Eyes
  • 16,287
  • 34
  • 113
  • 221
  • 1
    Did you consider simply putting a filter on the underlying collection view? Based upon what you wrote, you could eliminate the triggers and handle the filtering in your code behind. – Gayot Fow Apr 15 '14 at 21:24
  • Can you show me clear documentation for listview.datacontext only ? I found mostly for datagrid – Snake Eyes Apr 16 '14 at 04:57
  • It is independent of data context; in your case you would get the collection view source of _backup.Orders and cast it into ListCollectionView and then set the filter on it. Very straight forward. You can even use an anonymous delegate. I wrote the wiki tag over here http://stackoverflow.com/tags/listcollectionview/info if it's of any use – Gayot Fow Apr 16 '14 at 12:44

1 Answers1

1

First of all, implement the interface INotifyPropertyChanged (or a base class which implements that interface) for your class Order. Setup your properties correctly by using the OnPropertyChanged function provided by the interface. That is required since your ObservableCollection Orders does not get notified when an instance of an item in the list changes.

This might look as follows:

class Order : INotifyPropertyChanged
{
    // Boilerplate code..

    private bool _Visible ;

    public bool Visible
    {
        get { return _Visible; }
        set
        {
            if (_Visible == value) return;
            _Visible = value;
            OnPropertyChanged(() => _Visible);
        }
    }
}

Additionally you should implement the same functionality for your ObservableCollection Orders.

Your triggerevent should be fired as well when the Visible property changes.

0x8BADF00D
  • 962
  • 1
  • 8
  • 18