Vishal
Vishal

Reputation: 6368

How to check if item is null without typecasting it

I have a simple class called Person.cs as follows:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string City { get; set; }
}

I have a ViewModel called MainWindowViewModel.cs as follows:

public class MainWindowViewModel : INotifyPropertyChanged
{
    public MainWindowViewModel()
    {
        People = new ObservableCollection<Person>();
    }

    private ObservableCollection<Person> _people;
    public ObservableCollection<Person> People
    {
        get
        {
            return _people;
        }
        set
        {
            _people = value;
            OnPropertyChanged("People");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

}

I have a Datagrid in MainWindow.xaml as follows:

All is working fine upto this point. Now I want to delete the empty rows in DataGrid when it looses focus. I can do that as below :

private void maindg_LostFocus(object sender, RoutedEventArgs e)
{
    var list = (IList)maindg.ItemsSource;
    var elementType = list.GetType().GetGenericArguments()[0];
    var newElement = Activator.CreateInstance(elementType);

    foreach(var item in maindg.Items)
    {
        if((((Person)item).FirstName = null || ((Person)item).FirstName = "") && (((Person)item.LastName) = null || ((Person)item).LastName = "") && (((Person)item).City = null || ((Person)item).City = ""))
        {
            list.Remove(item);
        }
    }
}

But I am planning to create something like reusable control, so I cannot typecast item to Person object. So, how can I check if item is null or empty?

Upvotes: 0

Views: 843

Answers (5)

har07
har07

Reputation: 89295

One possible approach is using reflection :

  1. Use reflection to get all properties of each item.

  2. Then for each property, get the property's default value and compare it with item's property value. If item's property value equals to default value means current item is not empty and should'nt be removed.

Upvotes: 0

CJB
CJB

Reputation: 26

Option 1- Generic Type

You could create an interface for the list item type with an IsEmpty method, and make the custom control generic with a type constraint for this interface.

interface IEntity
{
    bool IsEmpty();
}

Then when you enumerate the list items, cast to IEntity:

var entity = item as IEntity;
if (entity == null || entity.IsEmpty())
{
    list.Remove(item);
}

The Person class implements IEntity, and in the IsEmpty method you cachecking the properties

Option 2- Delegate

Provide the custom control with a delegate that checks if the item is empty, which the developer would implement by performing the specific cast and checking of property values.

private Func<object, bool> _emptyCheckCallback;

This can be called when enumerating the items.

if (_emptyCheckCallback(item))
{
    list.Remove(item);
}

Upvotes: 1

pushpraj
pushpraj

Reputation: 13679

You have two options to simply the code

You can make use of dynamic if you are using c# 4.0

eg

    foreach (dynamic item in maindg.Items)
    {
        if ((item.FirstName = null || item.FirstName = "") && (item.LastName = null || item.LastName = "") && (item.City = null || item.City = ""))
        {
            list.Remove(item);
        }
    }

using dynamic you just need to have the required property available in order to be checked

or

typecast only once if the target type is fixed or you have a common interface of a common base class

    foreach (var item in maindg.Items)
    {
        Person p = item as Person;
        if ((p.FirstName = null || p.FirstName = "") && (p.LastName = null || p.LastName = "") && (p.City = null || p.City = ""))
        {
            list.Remove(item);
        }
    }

also to check both null and empty at the same time you can use the follows

string.IsNullOrEmpty(p.FirstName);

Upvotes: 0

Paras Mittal
Paras Mittal

Reputation: 1149

You can first check if typecasting the object is safe. eg.

 if ( item is Person )
 // safe to typecast now.

For different object you can check if else condition.

If you don't want if-else approach then i would recommend the answer by TGH. Since you need first name to check if the object is null then you can refer to interface and type cast the object to that interface. And for double check you can also check "if ( item is Person )".

Upvotes: 0

TGH
TGH

Reputation: 39258

I am assuming the FirstName property is common to all scenarios? If so, you can refer to an interface instead of the concrete classes. Just ensure that the objects in the collection implements the interface.

Upvotes: 0

Related Questions