Issue
I have an Observable Collection of a Hymn Class and another Observable Collection of a HymntType Class as shown below
public class Hymn
{
public int Id { get; set; }
public int HymnNumber { get; set; }
public string Title { get; set; }
public string HymnTypeName { get; set; }
public string Body { get; set; }
}
public class HymnType
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
}
I have initialized these classes with members on their respective page view models and I would like to use the Title property of the HymnType to filter the Hymn observable collection for only Hymns that have HymnTypeName Property equal to the HymnType Title property when the user selects the user selects it.
I am using LINQ but I get null for the list of Hymns after the filter, here is an example of the code I used for the filter.
public class HymnTypeContentPageViewModel : BaseViewModel
{
ObservableCollection<Hymn> _hymns;
public ObservableCollection<Hymn> Hymns
{
get => _hymns;
set => SetProperty(ref _hymns, value);
}
public HymnTypeContentPageViewModel(HymnType hymnType)
{
string keyword = hymnType.Title.ToLower();
Hymns = new ObservableCollection<Hymn>
{
new Hymn
{
HymnNumber = 201,
Title = "All Things Bright and Beautiful",
HymnTypeName = StaticStrings.AncientAndModern,
Body = "Test Body Ancient and Modern"
},
new Hymn
{
HymnNumber = 270,
Title = "He Arose",
HymnTypeName = StaticStrings.SomeOtherHymns,
Body = "Test Body Some Other Hymn"
},
};
Hymns = Hymns.Where(h => h.HymnTypeName.ToLower().Contains(keyword)) as ObservableCollection<Hymn>;
}
}
Both the HymnType Class Title Property and the Hymn Class HymnTypeName property use the StaticString class for their values so it is very unlikely that it is a typo. I have tried using a foreach loop instead of LINQ and I still get null.
Not that if I do not apply the filter, I do not get null and the app works perfectly.
Solution
If you use as ObservableCollection<Hymn> but the source collection (in your case an IEnumerable<Hymn>) is not an ObservableColletion<Hymn> the cast will result in null. Documentation of Where(...) extension)
Therefore you have to create a new ObservableCollection with this IEnumerable<Hymn> as source (in constructor).
// Filter the collection by contained keywords
var filteredList = Hymns?.Where(h => h.HymnTypeName.ToLower().Contains(keyword));
if(filteredList == null)
{
// if Hymns is null or the filtered collection is null
// return an empty list
Hymns = new ObservableCollection<Hymn>();
}
// create a new ObservableCollection with the filtered list
Hymns = new ObservableCollection<Hymn>(filteredList);
Here is a working Example
Answered By - Martin
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.