无法使用PRISM 5、MVVM和EF 6刷新WPF中的DataGrid
本文关键字:EF 刷新 WPF DataGrid 中的 MVVM PRISM | 更新日期: 2023-09-27 18:21:26
我的问题似乎很常见,但对于我在这里和其他网站上读到的所有帖子,我仍然没有找到解决方案。
我有一个相当简单的数据输入WPF模块——2个TextBoxes、3个ComboBoxes、1个DataGrid,然后是Submit和Clear按钮。(该应用程序/表单用于在会计数据库中创建总账账户。)我正在使用PRISM 5构建我的整个解决方案。(这是我第一次尝试如此复杂的东西,目前这是一次概念验证。)无论如何,我将所有WPF屏幕(UserControl/Views)绑定到适当的ViewModel。ViewModel又通过EF 6实体(db First)从MSSS数据库获取数据。当用户打开这个特定的WPF屏幕时,DataGrid会显示数据库中的所有现有记录。
除了一个例外,Submit(新记录)过程按照我的意愿工作:一个新条目被推送到MSSS数据库,文本框被清除,ComboBoxes被重置。然而,我想要的是1)刷新DataGrid,显示新记录,2)在网格中突出显示该新记录。然而,就我的一生而言,我无法做到这一点。注意:DataGrid绑定到数据库中的视图而不是表可能会有所不同。(同样,当应用程序第一次打开时,DataGrid显示正确。)
那么,我该如何更新DataGrid?????
以下是WPF视图的(浓缩的)XAML:
<UserControl x:Class="AcctMappingWpfModule.Views.CreateGLAcctsView"
other namespace declarations...
xmlns:vms="clr-namespace:AcctMappingWpfModule.ViewModels">
<UserControl.DataContext>
<vms:CreateGLAcctsViewModel />
</UserControl.DataContext>
...
<StackPanel ...>
<!-- Layout controls for 2 Text boxes & 3 ComboBoxes -->
...
<!-- Data grid of all Genl Ledger accts -->
<DataGrid x:Name="dgGLAccts"
IsReadOnly="True"
SelectionUnit="FullRow"
...
ItemsSource="{Binding Path=GLAccounts}" />
<WrapPanel >
<!-- Submit & Clear Buttons here -->
</WrapPanel>
</StackPanel>
以下是(浓缩的)ViewModel代码(省略了try/catch块):
namespace AcctMappingWpfModule.ViewModels
{公共类CreateGLAccctsViewModel:BindableBase,ICreateGLAccctesViewModel{专用TBLOADEntities上下文;private int _glAcctID=0;//其他私人字段。。。
// Ctor...
public CreateGLAcctsViewModel( )
{
this.SubmitCommand = new DelegateCommand(OnSubmit);
// Populate ICollectionViews - i.e., properties...
using (context = new TBLOADEntities())
{
// 3 properties behind ComboBoxes populated, then the DataGrid ppt...
List<vwGLAcct> accts = new List<vwGLAcct>();
accts = (from a in context.vwGLAcct select a).ToList<vwGLAcct>();
GLAccounts = CollectionViewSource.GetDefaultView(accts);
}
// Hook up selection change delegates, including...
GLAccounts.CurrentChanged += GLAccounts_CurrentChanged;
}
private void OnSubmit()
{
GLAccount glAcct = new GLAccount()
{
// Various properties set, then...
GlFsAcctTypeComboFK = this.SelectedFSAcctTypeComboID
};
using (context = new TBLOADEntities())
{
context.GlAcct.Add(glAcct);
context.SaveChanges();
// vwGLAcct is the EF entity of the MSSS db view...
List<vwGLAcct> accts = new List<vwGLAcct>();
accts = (from a in context.vwGLAcct select a).ToList<vwGLAcct>();
GLAccounts = CollectionViewSource.GetDefaultView(accts);
SelectedGLAcctID = glAcct.GlAcctID;
GLAccounts.Refresh();
}
}
private void GLAccounts_CurrentChanged(object sender, EventArgs e)
{
vwGLAcct current = GLAccounts.CurrentItem as vwGLAcct;
SelectedGLAcctID = current.GlAcctID;
}
public ICommand SubmitCommand { get; private set; }
public int SelectedGLAcctID
{
get
{ return _glAcctID; }
set
{
SetProperty(ref _glAcctID, value);
}
}
public ICollectionView GLAccounts { get; private set; }
}
}
1)为什么再次获得默认视图?(CollectionViewSource.GetDefaultView(accts))?确保accts是ObservableCollection,并且只获得一次默认视图,然后点击刷新它。
2) 那是窗户后面的密码吗?如果是,则dgGLAcccts.GetBindingExpression(DataGrid.ItemsSourceProperty).UpdateTarget()
您可以尝试将这些从您的更改为矿山
<DataGrid x:Name="dgGLAccts"
IsReadOnly="True"
SelectionUnit="FullRow"
SelectedItem="{Binding SelectedGLAccount}"
ItemsSource="{Binding Path=GLAccounts}" />
private vwGLAcct selectedGLAccount;
public vwGLAcct SelectedGLAccount
{
get
{
return selectedGLAccount;
}
set
{
if (selectedGLAccount != value)
{
selectedGLAccount = value;
this.RaisePropertyChanged(() => this.SelectedGLAccount);
}
}
}
private System.Collections.ObjectModel.ObservableCollection<vwGLAcct> gLAccounts;
public System.Collections.ObjectModel.ObservableCollection<vwGLAcct> GLAccounts
{
get
{
return gLAccounts ?? (gLAccounts = new System.Collections.ObjectModel.ObservableCollection<vwGLAcct>());
}
}
public CreateGLAcctsViewModel( )
{
this.SubmitCommand = new DelegateCommand(OnSubmit);
// Populate ICollectionViews - i.e., properties...
using (context = new TBLOADEntities())
{
// 3 properties behind ComboBoxes populated, then the DataGrid ppt...
List<vwGLAcct> accts = new List<vwGLAcct>();
accts.ForEach(a => this.GLAccounts.Add(a));
}
}
private void OnSubmit()
{
GLAccount glAcct = new GLAccount()
{
// Various properties set, then...
GlFsAcctTypeComboFK = this.SelectedFSAcctTypeComboID
};
using (context = new TBLOADEntities())
{
context.GlAcct.Add(glAcct);
context.SaveChanges();
// vwGLAcct is the EF entity of the MSSS db view...
this.GLAccounts.Add(glAcct);
this.SelectedGLAccount = glAcct;
}
(1)在ViewModel中,将您的GLAcccts更改为ObservableCollection
上的帐户类。别忘了NotifyPropertyChanged
(2) 如果需要的话,将CollectionViewSource放在xaml中,并将VM属性绑定到那里的源,如下所示:
<CollectionViewSource Source="{Binding GLAccts}" x:Key="AccountsCollection" >
(3) 然后,您可以将数据网格绑定到该集合,如下所示:
<DataGrid ItemsSource="{Binding Source={StaticResource AccountsCollection}}" ...
每当您对GLAcccts属性中的项目进行更改并提交了更改时,只需在上下文中加载另一个负载即可刷新它。
为了处理数据网格中选择/突出显示的最新添加,您只需要设置一个绑定到一个名为SelectedAccount
(或类似)的新VM属性,并且在数据网格上具有SelectedItem="{Binding SelectedAccount, Mode=TwoWay}"
当你提交一个新项目时,你可以将该项目保留为SelectedAccount,或者在刷新整个集合时,你也可以(通过键或其他方式)确定哪个是新项目。