为什么 collectionviewsource 在单击按钮时不更新数据网格
本文关键字:更新 数据 数据网 网格 collectionviewsource 单击 按钮 为什么 | 更新日期: 2023-09-27 18:36:15
我有两个视图模型,一个是mainViewModel,另一个是parentViewModel。我将主视图模型设置为主窗口网格的数据上下文,并将父视图模型设置为数据网格的数据上下文。我尝试使用实体框架生成的模型来更新数据网格,但在实现 INotifyPropertyChange 时出现错误,因此我创建了一个自定义模型并将实体框架模型中的数据映射到我的自定义模型。
父视图模型:
在本例中,父类是实体框架生成的模型,父类是我的自定义模型。
public class ParentViewModel : INotifyPropertyChanged
{
#region Constructor
/// <summary>
/// Initializes a new instance of Parent ViewModel class.
/// </summary>
public ParentViewModel()
{
_addParentCommand = new AddParentCommand(AddParent, IsExecutable);
Parentss = new Parents()
{
PLastName = null,
PFirstName = null,
PMiddleName = null,
PAddress = null,
PContactNo = null,
PEmail = null,
PUsername = null,
PPassword = null,
ValidationString = null
};
_parentCollection = new ObservableCollection<Parent>();
_parentsCollection = new ObservableCollection<Parents>();
//ParentsCollection = new ObservableCollection<Parents>();
_parentList = new List<Parent>();
_parentsList = new List<Parents>();
ViewSource = new CollectionViewSource();
ViewSource.Source = ParentsCollection;
Load();
}
#endregion
#region Events
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
#region Methods
/// <summary>
/// Checks if the application can execute a method.
/// </summary>
/// <param name="context">Data context</param>
/// <returns>bool</returns>
public bool IsExecutable(object context)
{
if (context != null)
{
var s = context as string;
s = s.Trim();
if (string.IsNullOrWhiteSpace(s))
{
return false;
}
return true;
}
return false;
}
/// <summary>
/// Loads the data from the database when the application starts.
/// </summary>
public void Load()
{
using (RegistrationEntities registrationContext = new RegistrationEntities())
{
_parentList = registrationContext.Parents.ToList();
for (int i = 0; i < _parentList.Count; i++)
{
Parents = new Parents()
{
PId = _parentList[i].P_Id,
PLastName = _parentList[i].P_LastName,
PFirstName = _parentList[i].P_FirstName,
PMiddleName = _parentList[i].P_MiddleName,
PAddress = _parentList[i].P_Address,
PContactNo = _parentList[i].P_ContactNo,
PEmail = _parentList[i].P_Email,
PUsername = _parentList[i].P_Username,
PPassword = _parentList[i].P_Password,
PCreatedOn = _parentList[i].P_CreatedOn,
PUpdatedAt = _parentList[i].P_UpdatedAt
};
_parentsCollection.Add(Parents);
//ParentsCollection.Add(Parents);
}
}
}
public void Load2()
{
//for (int i = 0; i < _parentsList.Count; i++)
//{
// _parentsCollection.Add(_parentsList[i]);
//}
}
/// <summary>
/// Add a new Parent.
/// </summary>
/// <param name="context">Data context</param>
public void AddParent(object context)
{
using (RegistrationEntities registrationContext = new RegistrationEntities())
{
Parent parent = new Parent
{
P_LastName = Parentss.PLastName,
P_FirstName = Parentss.PFirstName,
P_MiddleName = Parentss.PMiddleName,
P_Address = Parentss.PAddress,
P_ContactNo = Parentss.PContactNo,
P_Email = Parentss.PEmail,
P_Username = Parentss.PUsername,
P_Password = Encrypt(Parentss.PPassword),
P_CreatedOn = DateTime.Now.Date + DateTime.Now.TimeOfDay,
P_UpdatedAt = DateTime.Now.Date + DateTime.Now.TimeOfDay
};
registrationContext.Parents.Add(parent);
try
{
registrationContext.SaveChanges();
_parentList = registrationContext.Parents.ToList();
_parentsCollection.Clear();
//ParentsCollection.Clear();
for (int i = 0; i < _parentList.Count; i++)
{
Parents = new Parents()
{
PId = _parentList[i].P_Id,
PLastName = _parentList[i].P_LastName,
PFirstName = _parentList[i].P_FirstName,
PMiddleName = _parentList[i].P_MiddleName,
PAddress = _parentList[i].P_Address,
PContactNo = _parentList[i].P_ContactNo,
PEmail = _parentList[i].P_Email,
PUsername = _parentList[i].P_Username,
PPassword = _parentList[i].P_Password,
PCreatedOn = _parentList[i].P_CreatedOn,
PUpdatedAt = _parentList[i].P_UpdatedAt
};
_parentsCollection.Add(Parents);
ViewSource.View.Refresh();
//ParentsCollection.Add(Parents);
}
MessageBox.Show("Success!");
Parentss.PLastName = null;
Parentss.PFirstName = null;
Parentss.PMiddleName = null;
Parentss.PAddress = null;
Parentss.PContactNo = null;
Parentss.PEmail = null;
Parentss.PUsername = null;
Parentss.PPassword = null;
}
catch (DbEntityValidationException ex)
{
foreach (var eve in ex.EntityValidationErrors)
{
MessageBox.Show(String.Format("Entity of type '"{0}'" in state '"{1}'" has the following validation errors: ", eve.Entry.Entity.GetType().Name, eve.Entry.State));
foreach (var ve in eve.ValidationErrors)
{
MessageBox.Show(String.Format("- Property: '"{0}'", Value: '"{1}'", Error: '"{2}'"", ve.PropertyName, eve.Entry.CurrentValues.GetValue<object>(ve.PropertyName), ve.ErrorMessage));
}
}
}
}
}
public string Encrypt(string password)
{
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
md5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(password));
byte[] result = md5.Hash;
StringBuilder str = new StringBuilder();
for (int i = 0; i < result.Length; i++)
{
str.Append(result[i].ToString("x2"));
}
return str.ToString();
}
#endregion
#region Commands and Properties
private ICommand _addParentCommand;
/// <summary>
/// Gets or sets an ICommand interface.
/// </summary>
public ICommand AddParentCommand
{
get { return _addParentCommand; }
set { _addParentCommand = value; }
}
/// <summary>
/// Gets or sets a Parent class.
/// </summary>
public Parents Parentss
{
get;
set;
}
public Parents Parents
{
get;
set;
}
private List<Parent> _parentList;
public List<Parent> ParentList
{
get { return _parentList; }
set { _parentList = value; OnPropertyChanged("ParentList"); }
}
private ObservableCollection<Parent> _parentCollection;
public ObservableCollection<Parent> ParentCollection
{
get { return _parentCollection; }
set { _parentCollection = value; }
}
private List<Parents> _parentsList;
public List<Parents> ParentsList
{
get { return _parentsList; }
set { _parentsList = value; }
}
private ObservableCollection<Parents> _parentsCollection;
public ObservableCollection<Parents> ParentsCollection
{
get { return _parentsCollection; }
set { _parentsCollection = value; }
}
public CollectionViewSource ViewSource { get; set; }
#endregion
}
XAML:
<Grid DataContext="{StaticResource mainViewModel}">
<DataGrid x:Name="dgvParent" Grid.Row="1" HorizontalAlignment="Stretch" Height="Auto" VerticalAlignment="Stretch" Width="Auto" SelectionMode="Single" BorderThickness="2" Style="{StaticResource AzureDataGrid}" AutoGenerateColumns="False" AlternatingRowBackground="LightBlue" ItemsSource="{Binding ViewSource.View}" DataContext="{DynamicResource parentViewModel}" CanUserAddRows="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding PId}" FontWeight="Bold" Header="Id" />
<DataGridTextColumn Binding="{Binding PLastName}" FontWeight="Bold" Header="Last Name" />
<DataGridTextColumn Binding="{Binding PFirstName}" FontWeight="Bold" Header="First Name" />
<DataGridTextColumn Binding="{Binding PMiddleName}" FontWeight="Bold" Header="Middle Name" />
<DataGridTextColumn Binding="{Binding PAddress}" FontWeight="Bold" Header="Address" />
<DataGridTextColumn Binding="{Binding PContactNo}" FontWeight="Bold" Header="Contact Number" />
<DataGridTextColumn Binding="{Binding PEmail}" FontWeight="Bold" Header="Email" />
<DataGridTextColumn Binding="{Binding PCreatedOn}" FontWeight="Bold" Header="Created On" />
<DataGridTextColumn Binding="{Binding PUpdatedAt}" FontWeight="Bold" Header="Updated At" />
</DataGrid.Columns>
</DataGrid>
这就是
我在项目中所做的:
public ICollectionView MyView{ get; set; }
//ctor
public ParentViewModel()
{
//...
ParentsCollection= new ObservableCollection<Parents>();
MyView= CollectionViewSource.GetDefaultView(ParentsCollection);
//...
}
<DataGrid ItemsSource="{Binding MyView}"/>
顺便说一句,如果你的绑定不起作用,在运行时使用 Snoop 检查 DataContext 和 BindingExpressions。它始终是两种;)之一
我的回答并不是一个真正的答案——更像是一系列的抱怨和建议——但它不适合评论框,所以我把它放在这里。
- 这里有很大的清理和改进空间,尤其是在涉及变量名称和多个外观相似的变量定义时。
- 看起来您没有包含按钮定义,因此我们不知道您的
AddParentCommand
是否正在执行。 - 如果你每次都要完全清除和重建集合,那么拥有
ObservableCollection
是没有意义的;你可以把它留作一个List
,并通知列表的属性发生了变化,但正确利用ObservableCollection
的力量会更好。 - 我不相信你的
CollectionViewSource
会给你带来任何东西,除了可能帮助你从你实际上没有在你的房产上筹集PropertyChanged
的事实中恢复过来。
尝试先让更简单版本的代码在没有数据库持久性的情况下工作。