在不引用Collection的情况下向Datagrid的ItemsSource添加新项

本文关键字:Datagrid ItemsSource 添加 新项 情况下 引用 Collection | 更新日期: 2023-09-27 18:11:54

假设我有一个Person类,如下所示:

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

在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:

中有一个数据网格
<Window.DataContext>
    <local:MainWindowViewModel />
</Window.DataContext>
<DataGrid x:Key="maindg" ItemsSource="{Binding People}" KeyDown="maindg_KeyDown"/>

现在在MainWindow.xaml.cs我想做下面的东西不引用MainWindowViewModel:

private void maindg_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Key != Key.Enter) return;
    MainWindowViewModel.People.Add(new Person());
}

我试过了:

private void maindg_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Key != Key.Enter) return;
    maindg.ItemsSource.Cast<object>().ToList().Add(new Person());
}

但是上述尝试失败了。我的意思是我没有看到一个新的行添加到DataGrid

在不引用Collection的情况下向Datagrid的ItemsSource添加新项

不要使用LINQ。Cast<>()生成对象的新IEumerable, ToList创建原始列表的副本,这就是为什么对该列表的任何更改都不会更改实际列表的原因。

就像这样做一个标准的强制转换:

var list = (IList<Person>)maindg.ItemsSource;
list.Add(new Person());

或者让它更通用:

var list = (IList)maindg.ItemsSource;
list.Add(new Person());

编辑(对问题第二部分的回答):

这是一个通用的方法,可以在不知道列表类型的情况下为它创建一个新实例。

假定ItemsSourcegeneric集合,并且泛型元素有一个公共的无参数构造函数。

var list = (IList)maindg.ItemsSource;
var elementType = list.GetType().GetGenericArguments()[0];
var newElement = Activator.CreateInstance(elementType);
list.Add(newElement);