I am trying to create popup with a generic filter for a list view. I want to use the parameter 'T' to cast a new object with. I have a TextBox and a ListView in a control. My 'BaseClass' has the shared property that multiple classes inherit from. In the below example, the classes City, Company, and Contact all inherit from BaseClass. These different classes are the ones being passed as T. My VM is declared as such:
public class SearchViewModel<T> : BaseViewModel
where T : BaseClass, new()
{
...
}
My ListView's Itemsource is bound to "Items"
public ICollectionView Items { get; set; }
My TextBox is bound to "SearchText". At present I have it setup as follows:
private string _SearchText;
public string SearchText
{
get => _SearchText;
set
{
_SearchText = value;
OnPropertyChanged(nameof(SearchText));
if (string.IsNullOrEmpty(value))
Items.Filter = null;
else
{
var typedText = value.ToLower();
switch (typeof(T).Name)
{
case "City":
Items.Filter = new Predicate<object>(o => ((City)o).FilterByName.ToLower().Contains(typedText));
break;
case "Company":
Items.Filter = new Predicate<object>(o => ((Company)o).FilterByName.ToLower().Contains(typedText));
break;
case "Contact":
Items.Filter = new Predicate<object>(o => ((Contact)o).FilterByName.ToLower().Contains(typedText));
break;
}
}
}
}
I would like to do something like this:
private string _SearchText;
public string SearchText
{
get => _SearchText;
set
{
_SearchText = value;
OnPropertyChanged(nameof(SearchText));
if (string.IsNullOrEmpty(value))
Items.Filter = null;
else
{
Items.Filter = new Predicate<object>(o => ((T)o).FilterByName.ToLower().Contains(value.ToLower()));
}
}
}
Doing like this, the compiler does not give any complaints. However, during runtime I get the following error:
System.NullReferenceException: 'Object reference not set to an instance of an object.'
Now the question: Is there a way to use 'T' to cast the class for the filter?
EDIT:
Adding photo of debug results based on Dave's suggestion
UPDATE:
1) Response to Duplicate: This is not a question about the Null reference, but how to cast a generic parameter as a class.
2) The error is thrown at
Items.Filter = new Predicate<object>(o =>
((T)o).FilterByName
.ToLower()
.Contains(value.ToLower()))