Filter itemssource of one control with the selected value of another control in WPF
I have a combobox and a listbox in a WPF window.
The combobox's itemssource is set to a List of all Team objects. Team has 2 properties (TeamId and TeamName).
The listbox's itemssource is set to a List of all Player objects. Player on of Players pr开发者_运维技巧operties is TeamId.
I would like to filter the list of Players in the Listbox to only show those Players whose TeamId matches the TeamId of the SelectedItem in my combobox.
I would prefer to do this all in XAML but I'm not really sure on what the correct way to do it in C# would be either. Any help would be appreciated.
I'm not sure you can do it entirely in xaml, i think you might need a tiny bit of work somewhere else. This is how i did it for something else.
Wrap your collection with a CollectionViewSource in your xaml (this makes one that has a sort on a specific property name):
<CollectionViewSource x:Key="ViewName" Source="{Binding YourBinding}">
<CollectionViewSource.SortDescriptions>
<comp:SortDescription PropertyName="Name" Direction="Ascending" />
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
somewhere else, bind your listview to have this source as the itemssource:
<ListView x:Name="MyList" ItemsSource="{Binding Source={StaticResource ViewName}}" />
then somewhere in code, i have mine on a textbox property change listener, but you get the general idea. the ICollectionView interface has a filter member that you can use to filter things out.
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
var text = FilterTextBox.Text;
var source = MyList.Items as ICollectionView;
if (string.IsNullOrWhiteSpace(filter))
{
source.Filter = null;
}
else
{
source.Filter = delegate(object item)
{
var s = item as INamedItem;
return s.Name.IndexOf(filter, StringComparison.CurrentCultureIgnoreCase) != -1;
};
}
}
Firstly, change all your bound collections to ObservableCollection.
Then, on the combobox, bind the SelectedValue to another property on your DataContext of type Team (you have implemented INotifyPropertyChanged right?). When the SelectedValue changes, refresh the ListBox's bound collection with a filtered list from the collection of all players:
public ObservableCollection<Team> Teams { get;set;}
public ObservableCollection<Player> Players { get;set;}
private List<Player> AllPlayers {get;set}
public Team CurrentTeam
{
get
{
return this._currentTeam;
}
set
{
this._currentTeam = value;
this.Players = new ObservableCollection(this.AllPlayers.Where(x => x.TeamId = this._currentTeam.TeamId));
RaisePropertyChanged("CurrentTeam");
}
}
This is the quickest and easist way to do it. You could probably achieve this through CollectionView, but I think this is simpler to understand.
精彩评论