Reputation: 6368
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
Reputation: 89295
One possible approach is using reflection :
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
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
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
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
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