无法使用PRISM 5,MVVM和EF 6刷新WPF中的DataGrid

时间:2014-09-09 17:47:43

标签: c# wpf entity-framework mvvm datagrid

我的问题似乎很常见,但是,对于我在这里和其他网站上阅读过的所有帖子,我仍然没有找到解决方案。

我有一个相当简单的数据输入WPF模块 - 2个TextBoxes,3个ComboBoxes,1个DataGrid,然后是Submit和Clear按钮。 (应用程序/表单用于在会计数据库中创建总帐帐户。)我正在使用PRISM 5构建我的整个解决方案。(这是我第一次涉及任何远程复杂的事情,目前它是一个证据 - 概念上的努力。)无论如何,Iam将所有WPF屏幕(UserControl / Views)绑定到适当的ViewModel。 ViewModel依次通过EF 6实体(DB First)从MSSS db获取其数据。当用户打开此特定WPF屏幕时,DataGrid将显示数据库中的所有现有记录。

除了一个例外,提交(新记录)过程按我的意愿工作:新条目被推送到MSSS数据库,文本框被清除,组合框被重置。然而,我当时想要的是1)要刷新的DataGrid,显示新记录,以及2)要在网格中突出显示的新记录。但是对于我的生活,我无法做到这一点。注意:数据网格绑定到数据库中的视图而不是表格可能会有所不同。 (同样,当应用程序首次打开时,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

{     public class CreateGLAcctsViewModel:BindableBase,ICreateGLAcctsViewModel     {         私人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; }
}

}

3 个答案:

答案 0 :(得分:0)

1)为什么你再次获得默认视图? (CollectionViewSource.GetDefaultView(accts))提交后?确保accts是一个ObservableCollection并只获取一次默认视图,然后点击刷新它。

2)窗口背后的代码是什么?若有,dgGLAccts.GetBindingExpression(DataGrid.ItemsSourceProperty).UpdateTarget()

答案 1 :(得分:0)

您可以尝试将这些从您的更改为地雷

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

答案 2 :(得分:0)

(1)在您的ViewModel中,将您的GLAccts更改为ObservableCollection的任何帐户类。别忘了NotifyPropertyChanged

(2)在你的xaml中放置CollectionViewSource(如果你需要的话),然后将你的VM属性绑定到源,如下所示:

<CollectionViewSource Source="{Binding GLAccts}" x:Key="AccountsCollection" >

(3)然后,您可以将datagrid绑定到该集合,如下所示:

<DataGrid ItemsSource="{Binding Source={StaticResource AccountsCollection}}" ...

每当您对该GLAccts属性中的项目进行更改并提交更改时,只需在上下文中使用其他负载刷新它。

为了处理数据网格中选定/突出显示的最新添加,您只需设置绑定到名为SelectedAccount(或类似)的新VM属性以及DataGrid上的新属性有SelectedItem="{Binding SelectedAccount, Mode=TwoWay}"

当您提交新项目时,您可以将该项目保留为SelectedAccount,或者可以刷新整个集合,您可以计算出哪个是新项目(按键或其他内容)。