In WPF, I have a ListView
which is bounded to a Dictionary (InpLangList
) and a CheckBox
bounded with a boolean(IsShowEmptyFields
) property.
Eg. private Dictionary<string, string> _langList = new Dictionary<string, string>();
<ListView ItemsSource="{Binding InpLangList, Mode=TwoWay}" >
<ListView.View>
<GridView>
<GridViewColumn Header="Id" Width="Auto" DisplayMemberBinding="{Binding Key}" />
<GridViewColumn Header="Values" Width="Auto" DisplayMemberBinding="{Binding Value}" />
</GridView>
</ListView.View>
</ListView>
public Dictionary<string, string> InpLangList
{
get { return _langList ; }
set
{
_langList = value;
NotifyPropertyChanged();
}
}
(...)
InpLangList.Add("id1","One");
InpLangList.Add("id2","");
InpLangList.Add("id3","");
InpLangList.Add("id4","Four");
InpLangList.Add("id5","Five");
(...)
private bool _isShowEmptyFields;
public bool IsShowEmptyFields
{
get { return _isShowEmptyFields; }
set
{
_isShowEmptyFields = value;
NotifyPropertyChanged();
}
}
What I need is, if Checkbox is checked, then I want to display only the empty fields, i.e.
InpLangList.Add("id2","");
InpLangList.Add("id3","");
should be displayed in the ListView
else entire InpLangList
should be displayed in the ListView.
Use CollectionView:
ViewModel:
// Actual data source
Dictionary<string, string> inpLangList = new Dictionary<string, string>();
// A presentation of your data that you can group, sort, filter, etc
public ICollectionView InpLangList { get; set; }
private bool _isShowEmptyFields;
public bool IsShowEmptyFields
{
get { return _isShowEmptyFields; }
set
{
_isShowEmptyFields = value;
// if the presentation of your data is assigned - filter it
InpLangList?.Refresh();
}
}
// ViewModel constructor
public VM()
{
inpLangList.Add("id1", "One");
inpLangList.Add("id2", "");
inpLangList.Add("id3", "");
inpLangList.Add("id4", "Four");
inpLangList.Add("id5", "Five");
// note what's going next:
// assigning the data source to it's presentation (view)
InpLangList = CollectionViewSource.GetDefaultView(inpLangList);
// assigning filter that will be applied to your data source
// before the showing it within the UI
InpLangList.Filter = (obj) =>
{
if (!(obj is KeyValuePair<string, string> pair))
return false;
return !IsShowEmptyFields || string.IsNullOrEmpty(pair.Value);
};
}
View:
<CheckBox IsChecked="{Binding IsShowEmptyFields}" Content="Empty only"/>
<ListView ItemsSource="{Binding InpLangList}" >
<ListView.View>
<GridView>
<GridViewColumn Header="Id" Width="Auto" DisplayMemberBinding="{Binding Key}" />
<GridViewColumn Header="Values" Width="Auto" DisplayMemberBinding="{Binding Value}" />
</GridView>
</ListView.View>
</ListView>