将新项添加到Datagrid的ItemsSource,而不引用Collection

时间:2014-07-08 15:46:56

标签: c# wpf xaml datagrid

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

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的新行。

1 个答案:

答案 0 :(得分:2)

不要使用LINQ。 Cast<>()生成了一个新的IEumerable个对象,而ToList创建了原始列表的副本,这就是为什么对该列表的任何更改都不是&#39}的原因。改变真实的清单。

做这样的标准演员:

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