如何在不进行类型转换的情况下检查item是否为null

时间:2014-07-09 04:02:14

标签: c# wpf datagrid

我有一个名为Person.cs的简单类,如下所示:

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

我有一个名为MainWindowViewModel.cs的ViewModel,如下所示:

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));
        }
    }

}

我在MainWindow.xaml中有一个Datagrid,如下所示:

到目前为止,一切正常。现在我想在DataGrid失去焦点时删除它们中的空行。我可以这样做:

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);
        }
    }
}

但是我打算创建类似可重用控件的东西,所以我不能将item类型转换为Person对象。那么,我该如何检查item是空还是空?

5 个答案:

答案 0 :(得分:1)

选项1-通用类型

您可以使用IsEmpty方法为列表项类型创建接口,并使用此接口的类型约束使自定义控件通用。

interface IEntity
{
    bool IsEmpty();
}

然后,当您枚举列表项时,转换为IEntity:

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

Person类实现IEntity,并且在IsEmpty方法中缓存属性

选项2-代表

为自定义控件提供一个委托,该委托检查项是否为空,开发人员将通过执行特定的强制转换和检查属性值来实现该项。

private Func<object, bool> _emptyCheckCallback;

枚举项目时可以调用它。

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

答案 1 :(得分:0)

我假设FirstName属性对所有场景都是通用的?如果是这样,您可以引用接口而不是具体类。只需确保集合中的对象实现接口。

答案 2 :(得分:0)

您可以先检查对象的类型转换是否安全。例如

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

对于不同的对象,您可以检查是否有其他情况。

如果您不想要if-else方法,那么我会推荐TGH的答案。由于您需要使用名字来检查对象是否为null,因此您可以参考接口并键入将对象强制转换为该接口。对于仔细检查,您还可以检查&#34; if(item is Person)&#34;。

答案 3 :(得分:0)

您只需两个选项就可以使用代码

如果您使用的是c#4.0

,则可以使用dynamic

例如

    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);
        }
    }

使用动态,您只需要提供所需的属性即可进行检查

如果目标类型是固定的,或者您有一个公共基类的公共接口

,则只运行一次类型转换
    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);
        }
    }

同时检查null和empty,同时可以使用以下

string.IsNullOrEmpty(p.FirstName);

答案 4 :(得分:0)

一种可能的方法是使用反射:

  1. Use reflection to get all properties of each item

  2. 然后为每个属性get the property's default value进行比较 具有item的属性值。如果item的属性值等于默认值,则表示当前item不为空,且不应删除。