0

Пытаюсь освоить WPF с паттерном MVVM После добавления новых данных, не обновляется DataGrid.

Model:

public class ModelUser : INotifyPropertyChanged
    {
        public int _iduser;
        public string _secondname;
        public string _firstname;
        public string _middlename;
        public string _datebirth;
        public string _gender;
        public string _division;
    public int iduser
    {
        get { return _iduser;}
        set { _iduser = value; OnPropertyChanged("iduser"); }
    }
    public string secondname
    {
        get { return _secondname; }
        set { _secondname = value; OnPropertyChanged("secondname"); }
    }
    public string firstname
    {
        get { return _firstname; }
        set { _firstname = value; OnPropertyChanged("firstname"); }
    }
    public string middlename
    {
        get { return _middlename; }
        set { _middlename = value; OnPropertyChanged("middlename"); }
    }
    public string datebirth
    {
        get { return _datebirth; }
        set { _datebirth = value; OnPropertyChanged("datebirth"); }
    }
    public string gender
    {
        get { return _gender; }
        set { _gender = value; OnPropertyChanged("gender"); }
    }
    public string division
    {
        get { return _division; }
        set { _division = value; OnPropertyChanged("division"); }
    }

    public static List<ModelUser> GetUsers()
    {
        using (dbEntities db = new dbEntities())
        {
            var query = db.users.ToList().Join(db.division,
                    u => u.iddivision,
                    d => d.iddivision,
                    (u, d) => new ModelUser
                    {
                        iduser = u.iduser,
                        firstname = u.firstname,
                        secondname = u.secondname,
                        middlename = u.middlename,
                        gender = u.gender,
                        datebirth = u.datebirth.ToString("d"),
                        division = d.namedivision
                    }).ToList();

            return query;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    void OnPropertyChanged(string property)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
    }
} 

VM:

  public class UserWindowMainModel : INotifyPropertyChanged
    {
        public ObservableCollection<ModelUser> UsersData { get; set; }
    public UserWindowMainModel()
    {
        UsersData = new ObservableCollection&lt;ModelUser&gt;(ModelUser.GetUsers());
    }

    public event PropertyChangedEventHandler PropertyChanged;
    void OnPropertyChanged(string property)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
    }
}

XAML:


<DataGrid x:Name="dgUsers" 
                              HorizontalAlignment="Left" 
                              Height="300" Margin="20,20,0,0"
                              Width="704"
                              CanUserReorderColumns="False" 
                              SelectionMode="Single" 
                              IsReadOnly="True" 
                              AutoGenerateColumns="False" 
                              VerticalAlignment="Top"
                              VirtualizingPanel.ScrollUnit="Pixel"
                              ItemsSource="{Binding Path=UsersData}">
                        <DataGrid.Columns>
                            <DataGridTextColumn Width="30" Binding="{Binding iduser}" Header="№"/>
                            <DataGridTextColumn Width="Auto" Binding="{Binding secondname}" Header="Фамилия"/>
                            <DataGridTextColumn Width="Auto" Binding="{Binding firstname}" Header="Имя"/>
                            <DataGridTextColumn Width="Auto" Binding="{Binding middlename}" Header="Отчество"/>
                            <DataGridTextColumn Width="Auto" Binding="{Binding datebirth}" Header="Дата рождения"/>
                            <DataGridTextColumn Width="Auto" Binding="{Binding gender}" Header="Пол"/>
                            <DataGridTextColumn Width="*" Binding="{Binding division}" Header="Подразделение"/>
                        </DataGrid.Columns>
</DataGrid>

Добавление в таблицу:

private void buttAdd_Click(object sender, RoutedEventArgs e)
        {
            using (dbEntities db = new dbEntities())
            {
                    users users = new users
                    {
                        secondname = txtSecondName.Text.Trim(),
                        firstname = txtFirstName.Text.Trim(),
                        middlename = txtMidName.Text.Trim(),
                        datebirth = dpBirth.SelectedDate.Value,
                        gender = cbGender.SelectedValue.ToString(),
                        iddivision = int.Parse(cbDivision.SelectedValue.ToString())
                    };
                db.users.Add(users);
                db.SaveChanges();
                MessageBox.Show(&quot;Данные добавленны!&quot;, &quot;Выполненно&quot;, MessageBoxButton.OK, MessageBoxImage.Information);

badcoder
  • 25
  • 1
  • 6
  • При добавлении куда? Где это добавление? – EvgeniyZ Aug 14 '20 at 14:41
  • @EvgeniyZ В таблицу. Добавил в вопрос добавление. – badcoder Aug 14 '20 at 15:02
  • Нечнем с того, что buttAdd_Click — это не MVVM. Сама работа с базой данных по правилам MVVM должна быть отдельной моделью, а не постоянно инициализироваться в разных местах. MessageBox это, по сути, тоже нарушение MVVM и не стоит его использовать. Теперь сам вопрос - вы добавили в базу, но как эта база связана с вашей логикой? Вот есть у вас ObservableCollection<ModelUser> UsersData, с ней хоть какие либо манипуляции проходят? Я лично не вижу, вы раз загнали туда данные и все, а обновлять что в ней кто будет?) – EvgeniyZ Aug 14 '20 at 15:04
  • @EvgeniyZ я не знаю как это сделать, поэтому и спрашиваю. – badcoder Aug 14 '20 at 15:16
  • Не знаете что? Вот у вас есть два листа бумаги, на одном вы написали слово "Привет!", появиться ли это на другом листе? Наверно нет, а что бы это появилось, вам нужен некий механизм, который будет писать сразу на 2 листа, верно? Ну так и сделайте класс, который будет иметь метод добавления и в этом методе пусть он добавляет в коллекцию и в базу сразу, это будет модель взаимодействия с DB, ее и используйте везде, где надо. – EvgeniyZ Aug 14 '20 at 15:20
  • Удалять и пересоздавать вопросы - не приветствуется на StackOverflow. Вам уже были даны ссылки на примеры ответов на подобные вопросы. Попробуйте вернуться к удаленному вопросу, заглянуть там в комментарии и еще раз попробовать ознакомиться с ответами по предоставленным ссылкам. Попробуйте сначала без БД, просто создайте ViewModel, засуньте туда ObservableCollection, добавьте в нее что-ниубдь, пусть даже в коде конструктора, и убедитесь что данные отображаются, и уже потом начнайте интеграцию с базой. – aepot Aug 14 '20 at 16:22

1 Answers1

0

В кнопке вместо события и метода buttAdd_Click лучше использовать команду. Тогда это будет ложится под паттерн MVVM. Выглядеть это будет примерно так:

XAML:

<Button Content="Добавить"
        Command="{Binding AddCommand}"/> 

Далее в классе ViewModel создаёте свойство AddCommand, типа RelayCommand.

ViewModel.cs:

public RelayCommand AddCommand => new RelayCommand(AddMethod);
private void AddMethod(object obj)
{
    //метод добавления в таблицу...
    OnPropertyChanged("UsersData"); 
}

Класс RelayCommand реализует интерфейс ICommand. Как его реализовать есть в статье https://metanit.com/sharp/wpf/22.3.php. В метод AddMethod - вставь код, который выполнялся методом buttAdd_Click. В конце вызови метод обновления OnPropertyChanged. Обрати внимание, что метод AddMethod должен принимать параметр типа object.

Nikolay
  • 16
  • 1