Display Items in ComboBox dependent on a Property
I've got a combobox that is bound to a List<Person>
(ItemsSource is set in CodeBehind).
<ComboBox Width="120" Background="White" DisplayMemberPath="Name" />
So the names of all persons are added to the List.
Because it's not necessary to show every name in the ComboBox, I added a property Hide
of type bool
. If this property is set to true, the name should not be shown in the combobox.
But how is it possible to add a condition to开发者_StackOverflow the Binding of the combobox, so that only those persons are listed who are not supposed to be hidden.
EDIT: Regarding answers, I added the following code:
{
List<Person> persons;
...
var collectionView = CollectionViewSource.GetDefaultView(persons);
collectionView.Filter = HideFilter;
}
...
private bool HideFilter(object item)
{
Person p = item as Person;
return p.Hide;
}
But this throws a TargetInvocationException on collectionView.Filter = HideFilter;
.
You could either filter in the code behind, or you could use a item template to bind visibility of the Item to the isHiden property (with a boolean to visilbility converter). Your XAML code would be:
<ComboBox Grid.Column="1" Grid.Row="0" >
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Visibility="{Binding IsVisible}" Text="{Binding Name}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
public class person
{
public person(string n, Visibility v)
{
Name = n;
IsVisible = v;
}
public string Name {get;set;}
public Visibility IsVisible { get; set; }
}
You need to add a filter to the CollectionViewSource of the data source, your list, you can get this collection with the static method CollectionViewSource.GetDefaultView(list)
you'll get a nice interface where you can add a filter that says (hide = false)
you can apply linq query on the List before making it a source
List<Person> persons = new List<Person> ();
var Filter = from p in persons
where p.hide == false
select p;
Now renew persons and provide Filter as a list to it cast this Filter into List and defined it combo source...
persons = new List<Person>(Filter);
cbm.ItemSource = persons ;
My suggestions is to not do it this way. Why? It is not wrong, but it produces empty collapsed rows in the combobox! :/
In my case I had a list of five users and deleted all. But I had still five tiny little clickable(!) rows inside of the combobox. oO
<ComboBox Grid.Column="1" Grid.Row="0" >
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Visibility="{Binding IsVisible}" Text="{Binding Name}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Instead I use code like shown below. It's my solution for a user list. When I mark a user as deleted (if selected, click on button, mark as deleted), it disappears from the list completely.
<ComboBox ItemsSource="{Binding Path=UserList}"
SelectedItem="{Binding SelectedUser}"
DisplayMemberPath="Name"
IsEnabled="{Binding SelectedUser.HasErrors, TargetNullValue=True, FallbackValue=True, ValidatesOnNotifyDataErrors=False, Converter={StaticResource Bool2BoolNot}}"
IsEditable="False"
>
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Deleted}" Value="True">
<DataTrigger.Setters>
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger.Setters>
</DataTrigger>
<DataTrigger Binding="{Binding Path=Special}" Value="True">
<DataTrigger.Setters>
<Setter Property="Foreground" Value="Red"/>
</DataTrigger.Setters>
</DataTrigger>
<DataTrigger Binding="{Binding Path=Super}" Value="True">
<DataTrigger.Setters>
<Setter Property="Foreground" Value="DarkRed"/>
</DataTrigger.Setters>
</DataTrigger>
</Style.Triggers>
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
精彩评论