为什么collectionviewsource在单击按钮时不更新数据网格?

时间:2016-02-25 02:41:51

标签: c# wpf entity-framework mvvm datagrid

我有两个viewmodel,一个是mainViewModel,另一个是parentViewModel。我将mainViewModel设置为主窗口网格的数据上下文,并将parentViewModel设置为我的datagrid的数据上下文。我尝试使用实体框架生成的模型来更新数据网格,但是当我实现INotifyPropertyChange时遇到错误,所以我创建了一个自定义模型并将实体框架模型中的数据映射到我的定制模型。

parentViewModel:

在这种情况下,Parent类是实体框架生成的模型,而Parents类是我自定义的模型。

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>

2 个答案:

答案 0 :(得分:0)

这就是我在项目中所做的事情:

public ICollectionView MyView{ get; set; }

//ctor
public ParentViewModel()
{
    //...
    ParentsCollection= new ObservableCollection<Parents>();
    MyView= CollectionViewSource.GetDefaultView(ParentsCollection);
    //...
}


<DataGrid ItemsSource="{Binding MyView}"/>

顺便说一句。如果绑定不起作用,请在运行时使用Snoop检查 DataContext BindingExpressions 。它总是两者中的一个;)

答案 1 :(得分:-1)

我的回答并不是一个真正的答案 - 更像是一系列投诉和建议 - 但它并不适合评论框,所以我把它放在这里。

  1. 这里有很多清理和改进的空间,特别是在你的变量名和多个看似相似的变量定义时。
  2. 您似乎没有包含按钮定义,因此我们不知道您的AddParentCommand是否正在执行。
  3. 如果您每次都要完全清除并重建集合,那么拥有ObservableCollection毫无意义;您可以将其保留为List并更改列表中的通知属性,但正确利用ObservableCollection的强大功能会更好。
  4. 我不相信你的CollectionViewSource正在为你赢得任何东西,除非你帮助你从你未真正在你的财产上提出PropertyChanged的事实中恢复过来。
  5. 尝试在没有数据库持久性的情况下,首先使用更简单的代码版本。