"Hiding" part of List

1.8k views Asked by At

Task:

I want to hide a part of my CSLA ChildList but without using any extra Columns in my Database. (like visible ? true / false)

Example: I have a List of all member. Im setting a filter which allows me to see only the member with the number 3. Now I can edit the filterd List. After removing the filter I can see the whole List again and the edited Members without saving between the actions.

Im ending up in having two Lists. One is the filtert and one of all Members. Maybe there are some commands I don't know?

Code:

    private int _selectedGroup;
    public int SelectedGroup
    {
        get
        {
            return _selectedGroup;
        }
        set
        {
            if (_selectedGroup!= value)
            {
                _selectedGroup= value;
                OnPropertyChanged(() => SelectedGroup);

                FilterByGroup();
            }
        }
    }

Calling the Filter Method after changing the numner to filter.

    private void FilterByProduktgrp()
    {
         // List All
         List = Model.ChildList;
         //Filtered List
         List = List.Where(c => c.ID == FilterID);
    }

Now I need to get the edited List into the Model.ChildList

3

There are 3 answers

1
Sheridan On BEST ANSWER

As Mark says, there are many ways to achieve your goal. Judging by your code so far, you seem to be approaching this problem from the same way that I would. That way is this... basically, you need one private collection property that will always hold the complete collection of items. Then you need another public collection property that is data bound to some UI container control.

Upon initialisation of your view model, fetch the data and fill up your private collection. This will be used to populate your data bound collection dependant upon whatever filter properties that you choose. You can even build this filtering process into the filter property setter if you prefer:

public YourDataType SelectedItem
{
    get { return selectedItem; }
    set
    {
        selectedItem = value;
        NotifyPropertyChanged("SelectedItem");
        FilteredCollection = new ObservableCollection<YourDataType>(
PrivateCollection.Where(i = i.SomeProperty == selectedItem.AnotherProperty).ToList());
    }
}
0
Mark Feldman On

There are lots of different ways to do this, one way is with data triggers. First create a model for each element in your list and provide a "Hidden" property:

public class Model
{
    public string Text { get; set; }
    public bool Hidden { get; set; }
}

Then create the list and bind with your items control:

theListBox.ItemsSource = new Model[] {
            new Model{Text="One", Hidden=false},
            new Model{Text="Two", Hidden=true},
            new Model{Text="Three", Hidden=false}
        };

Finally override the ListBoxItem style in the listbox and use a data trigger to hide any element that has Hidden set to true:

<ListBox Name="theListBox" DisplayMemberPath="Text">
        <ListBox.Resources>
            <Style TargetType="{x:Type ListBoxItem}">
                <Setter Property="Visibility" Value="Visible"/>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Hidden}" Value="True">
                        <Setter Property="Visibility" Value="Collapsed"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </ListBox.Resources>
    </ListBox>

But like I said, there are lots of other ways to do this too e.g. converters, attached properties etc.

0
JSJ On

I suggest you to have a look at CollectionViewSource which allow you to Sort, filter, Group etc.

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
        <ListBox ItemsSource={Binding Customers} />
    </Window>



    public class CustomerView
    {
       public CustomerView()
       {
            DataContext = new CustomerViewModel();
       }
    }

    public class CustomerViewModel
    {
        private ICollectionView _customerView;

        public ICollectionView Customers
        {
            get { return _customerView; }
        }

        public CustomerViewModel()
        {
            IList<Customer> customers = GetCustomers();
            _customerView = CollectionViewSource.GetDefaultView(customers);
        }
    }*

To filter a collection view you can define a callback method that determines if the item should be part of the view or not. That method should have the following signature: bool Filter(object item). Now set the delegate of that method to the Filter property of the CollectionView and you're done.

ICollectionView _customerView = CollectionViewSource.GetDefaultView(customers);
_customerView.Filter = CustomerFilter

private bool CustomerFilter(object item)
{
    Customer customer = item as Customer;
    return customer.Name.Contains( _filterString );
}

A good example here.