这是我的第一个问题,所以我会努力的。
我正在尝试使用ObservableCollection和MVVM“刷新”一个简单的WPF DataGrid控件,正如网络上的许多教程所述。
在上下文中,这些是我的模型分类:
(PersonViewModel.cs)
public class PersonViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private int _id;
private int _idAddress;
private string _name;
private int _age;
private string _address;
public int Id
{
get { return this._id; }
set
{
if (value != this._id)
{
this._id = value;
OnPropertyChanged();
}
}
}
public int IdAddress
{
get { return this._idAddress; }
set
{
if (value != this._idAddress)
{
this._idAddress = value;
OnPropertyChanged();
}
}
}
public string Name
{
get { return this._name; }
set
{
if (value != this._name)
{
this._name = value;
OnPropertyChanged();
}
}
}
public int Age
{
get { return this._age; }
set
{
if (value != this._age)
{
this._age = value;
OnPropertyChanged();
}
}
}
public string Address
{
get { return this._address; }
set
{
if (value != this._address)
{
this._address = value;
OnPropertyChanged();
}
}
}
private void OnPropertyChanged([CallerMemberName]String caller = null)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(caller));
}
}
}
(AddressViewModel.cs)
public class AddressViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private int _id;
private string _street;
private int _number;
public int Id
{
get { return this._id; }
set
{
if (value != this._id)
{
this._id = value;
OnPropertyChanged();
}
}
}
public string Street
{
get { return this._street; }
set
{
if (value != this._street)
{
this._street = value;
OnPropertyChanged();
}
}
}
public int Number
{
get { return this._number; }
set
{
if (value != this._number)
{
this._number = value;
OnPropertyChanged();
}
}
}
private void OnPropertyChanged([CallerMemberName]String caller = null)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(caller));
}
}
}
这是数据库模型的表示形式(无法上传图片<10个帖子)
地址
ID
街道
数字
人
ID
ID地址
姓名
年龄
地址--->此属性连接“街道”和“地址数”实体。
因此,如您所见,这是一个非常简单的示例。只是概念证明。问题是,每当我尝试通过Entity Framework 6和LINQ向数据库中添加新实体时,都不可避免地必须将该ViewModel实体添加到DataGrid的数据上下文中。
这是直到今天的代码:
public static Person CreatePerson(PersonViewModel personVM)
{
var person = new Person
{
IdAddress = personVM.IdAddress,
Name = personVM.Name,
Age = personVM.Age
};
try
{
using (var context = new OCDemoContext())
{
context.Database.Connection.Open();
context.Person.Add(person);
context.SaveChanges();
context.Database.Connection.Close();
}
}
catch
{
throw;
}
return person;
}
如您所见,这里需要在DataGrid中显示一列,该列连接Address数据库实体的两个属性:Street和Number,并将该值提供给PersonViewModel类的Address属性以在DataGrid中显示为一列。
将实体插入数据库后,将实体添加到DataGrid itemssource集合的代码:
// Add to the database
PersonsGateway.CreatePerson(personVM);
// Update view on DataGrid's itemssource collection
ViewModel model = this.xGrid.DataContext as ViewModel;
model.Persons.Insert(0, personVM);
XAML为:
<Window x:Class="OCDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" xmlns:local="clr-namespace:OCDemo">
<Window.Resources>
<local:ViewModel x:Key="xViewModel" />
</Window.Resources>
<Grid x:Name="xGrid" DataContext="{StaticResource xViewModel}">
<DataGrid x:Name="xDataGrid" Grid.Row="0" ItemsSource="{Binding Persons}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=Name}" Header="Name"/>
<DataGridTextColumn Binding="{Binding Path=Age}" Header="Age"/>
<DataGridTextColumn Binding="{Binding Path=Address}" Header="Address"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
和ViewModel.cs
public class ViewModel
{
public ObservableCollection<PersonViewModel> Persons { get; set; }
public ViewModel()
{
this.Persons = PersonsGateway.RetrievePersons();
}
}
T4 .tt文件已更新为MSDN - Updating code generation for data binding说明。
因此,在ObservableCollection场景中,可能仅依赖于将实体添加到数据库中,而不必始终将实体添加到itemssource集合中?
最佳答案
将您的 View 模型更改为以下内容
public class ViewModel
{
public ObservableCollection<PersonViewModel> Persons { get; private set; }
public ViewModel()
{
Persons = new ObservableCollection<PersonViewModel>();
Persons.AddRange(PersonsGateway.RetrievePersons().ToList());
}
}
重要的是,一次创建可观察的集合而不是重新创建它,而是依赖于更改通知,因此先创建它,然后使用标准方法来对其进行管理。
关于c# - 有没有一种方法可以使用ObservableCollection和MVVM刷新WPF DataGrid,而无需通知ItemsSource集合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32784941/