Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
5 / 5 / 0
Регистрация: 11.09.2021
Сообщений: 578
WPF

Редактирование данных в DataGrid через диалог

10.12.2023, 20:09. Показов 490. Ответов 3
Метки c# (Все метки)

Студворк — интернет-сервис помощи студентам
Как организовать редактирование данных через диалог?
Я сделал. Вроде работает.
Ожидаю замечания, примеры аналоги.

Доп. вопросы.
По общим правилам **Модель** должна реализовывать `INotifyPropertyChanged`?
Я сделал с реализацией `INotifyPropertyChanged`.

**Описание файлов:**
Student2 - Модель без `INotifyPropertyChanged`
StudentDialogVievModel - VievModel для случая, когда модель без `INotifyPropertyChanged`.
В данном решении проекта не используются.
Я их оставил для примера.

Student2
Кликните здесь для просмотра всего текста

C#
1
2
3
4
5
6
public class Student2
    {
        public int Id { get; set; }        
        public string FirstName { get; set; }
        public string LastName { get; set; }        
    }


Состав:
- WPF. .Net Framework;
- EF6, Framework;
- SQLite;
- --- --- --- --- --- --- --- --- --- ---;
- **Nuget:** System.Data.SQLite;

Проект: https://github.com/jhon65496/DialogWpfPublicApp01



Код
RelayCommand
Кликните здесь для просмотра всего текста

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class RelayCommand : ICommand
{
    Action<object> execute;
    Func<object, bool> canExecute;
 
    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }
 
    public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null)
    {
        this.execute = execute;
        this.canExecute = canExecute;
    }
 
    public bool CanExecute(object parameter)
    {
        return canExecute == null || canExecute(parameter);
    }
 
    public void Execute(object parameter)
    {
        execute(parameter);
    }
 
}



BaseVM
Кликните здесь для просмотра всего текста

C#
1
2
3
4
5
6
7
8
public class BaseVM : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public void RaisePropertyChanged([CallerMemberName] String propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}



Student(c использованием INotifyPropertyChanged)
Кликните здесь для просмотра всего текста

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class Student : BaseVM
    {   
 
        public int _id;
        public int Id
        {
            get { return _id; }
            set 
            {
                _id = value;
                RaisePropertyChanged(nameof(Id));
            }
        }
 
        public string _firstName;
        public string FirstName
        {
            get { return _firstName; }
            set 
            {
                _firstName = value;
                RaisePropertyChanged(nameof(FirstName));
            }
        }
 
 
        public string _lastName;
        public string LastName
        {
            get { return _lastName; }
            set 
            { 
                _lastName = value;
                RaisePropertyChanged(nameof(LastName));
            }
        }
       
    }



DbContextApp
Кликните здесь для просмотра всего текста

C#
1
2
3
4
5
6
7
8
9
public class DbContextApp : DbContext
{
    public DbContextApp() : base("DefaultConnection")
    {
 
    }
 
    public DbSet<Student> Students { get; set; }
}



StudentsViewModel
Кликните здесь для просмотра всего текста

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
public class StudentsViewModel : BaseVM
    {
        DbContextApp _dataContextApp;
        
        public StudentsViewModel()
        {
            this._dataContextApp = new DbContextApp();
            
            LoadData();
        }
        
        private ObservableCollection<Student> students;
        public ObservableCollection<Student> Students
        {
            get { return students; }
            set 
            {
                students = value;
 
                Debug.WriteLine($"ObservableCollection<Student> Students -- set ");
                // _dataContextApp.SaveChanges();
 
                RaisePropertyChanged(nameof(Students));
            }
        }
 
        private Student _selectedStudent;
        public Student SelectedStudent
        {
            get { return _selectedStudent; }
            set 
            {
                Debug.WriteLine($"Prop: SelectedStudent-- set ");
                if (_selectedStudent != value)
                {
                    _selectedStudent = value;
                    
                    Debug.WriteLine($"_selectedStudent.FirstName {_selectedStudent.FirstName}");
                    
                    RaisePropertyChanged(nameof(SelectedStudent));
                }
            }
        }
        
        RelayCommand editCommand;
        public RelayCommand EditCommand
        {
            get
            {
                return editCommand ??
                    (editCommand = new RelayCommand((selectedStudent) =>
                    {
                        Debug.WriteLine($"RelayCommand EditCommand -- get");
                        // получаем выделенный объект
                        Student studentSelected = selectedStudent as Student;
                        if (studentSelected == null) return;
 
                        Student studentNew = new Student
                        {
                            Id = studentSelected.Id,
                            LastName  = studentSelected.LastName,
                            FirstName = studentSelected.FirstName
                        };
 
                        StudentDialogVievModel studentDialogVievModel = new StudentDialogVievModel(studentNew);
                        StudentDialog studentDialog = new StudentDialog(studentNew);
                        studentDialog.DataContext = studentDialogVievModel;
 
                        if (studentDialog.ShowDialog() == true)
                        {
                            studentSelected.Id = studentDialogVievModel.Id;
                            studentSelected.FirstName = studentDialogVievModel.FirstName;
                            studentSelected.LastName  = studentDialogVievModel.LastName;
 
                            _dataContextApp.Entry(studentSelected).State = EntityState.Modified;
                            _dataContextApp.SaveChanges();                            
                        }
                    }));
            }
        }
 
        public void LoadData()
        {          
            this._dataContextApp.Students.Load();           // +***
            Students = this._dataContextApp.Students.Local; // 
        }
    }




StudentDialog.xaml
Кликните здесь для просмотра всего текста

XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<Window x:Class="DialogWpfPublicApp01.Views.StudentDialog"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:DialogWpfPublicApp01.Views"
        mc:Ignorable="d"
        Title="StudentDialog" Height="110" Width="350">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="20"/>
            <RowDefinition Height="20"/>
            <RowDefinition Height="40"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="100" />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <TextBlock Text="FirstNmae" />
        <TextBlock Text="LastName" Grid.Row="1" />
 
        <TextBox Text="{Binding FirstName}" Grid.Column="1" Grid.Row="0" />
        <TextBox Text="{Binding LastName}"  Grid.Column="1" Grid.Row="1" />
        
        <UniformGrid Grid.Row="2" Grid.Column="1" >
            <Button IsDefault="True" Click="Button_Click" >OK</Button>
            <Button IsCancel="True" >Отмена</Button>
        </UniformGrid>
        
    </Grid>
</Window>



StudentDialog.xaml.cs
Кликните здесь для просмотра всего текста

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public partial class StudentDialog : Window
{
    public Student _student { get; set; }
    public StudentDialog(Student student)
    {
        InitializeComponent();
        _student = student;
 
        DataContext = _student;
    }
 
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        DialogResult = true;
    }
}



MainWindow.xaml
Кликните здесь для просмотра всего текста

XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<Window x:Class="DialogWpfPublicApp01.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:DialogWpfPublicApp01"
        mc:Ignorable="d"
        Title="MainWindow" 
        Height="300" 
        Width="300">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="40"/>
        </Grid.RowDefinitions>
        <DataGrid Grid.Row="0"                                         
                    ItemsSource="{Binding Students}"
                    SelectedItem="{Binding SelectedStudent}"
                    AutoGenerateColumns="False"
                    CanUserAddRows="True"
                    GridLinesVisibility="Vertical"                                  
                    VerticalGridLinesBrush="DarkGray"
                    AlternatingRowBackground="LightGray"
                     >
            <DataGrid.Columns>
                <DataGridTextColumn Header="id"  Binding="{Binding Id}" Width="Auto"/>
                <DataGridTextColumn Header="Имя" Binding="{Binding FirstName}" Width="*"/>
                <DataGridTextColumn Header="Имя" Binding="{Binding LastName}" Width="*"/>
            </DataGrid.Columns>
        </DataGrid>
        
        <UniformGrid Grid.Row="1">
            <Button Content="Edit" Command="{Binding EditCommand}"
                    CommandParameter="{Binding SelectedStudent}"/>
        </UniformGrid>
    </Grid>
</Window>



MainWindow
Кликните здесь для просмотра всего текста

C#
1
2
3
4
5
6
7
8
9
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
 
        this.DataContext = new StudentsViewModel();
    }
}
Миниатюры
Редактирование данных в DataGrid через диалог  
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
10.12.2023, 20:09
Ответы с готовыми решениями:

Редактирование базы данных через DataGrid
Здравствуйте. Столкнулся с проблемой. Если вкратце - в Sql есть база данных, содержащая таблицы. В WPF приложении создал DataGrid. Вывожу...

Редактирование данных в базе через datagrid

Редактирование данных БД в DataGrid
Здравствуйте! Имеется программа, работающая с БД Microsoft Access. Все подключается, добавляется, удаляется через созданную программу...

3
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16125 / 11249 / 2888
Регистрация: 21.04.2018
Сообщений: 33,082
Записей в блоге: 2
10.12.2023, 22:02
Цитата Сообщение от dev3214 Посмотреть сообщение
Как организовать редактирование данных через диалог?
Два основных сценария
1) Собираются данные для редактирования (добавления), по завершению диалога проверяется результат завершения и сущность вызывавшая диалог сохраняет (если нужно) полученные данные;
2) В Диалог передаются нужные для сохранения методы и диалог сам сохраняет данные. Этот способ предпочителен, если возможны отказы в сохранении. Чтобы можно было продолжить редактирование.

В обоих случаях конструктор Диалога нужно скрыть. А его вызов производить через статический метод по типу StudentDialog.Show(режим, сущность, др. аргументы);. Метод может быть как void так и с возвращением результата. Зависит от условий задачи.

Добавлено через 11 минут
Цитата Сообщение от dev3214 Посмотреть сообщение
DataContext = _student;
... Так себе.
Не безопасно.
Лучше в ресурсы добавить локатор со свойствами для студента и интерфейса сохранения данных.
Из CB задать значения свойствам. А в XAML можно привязываться к ним.
1
5 / 5 / 0
Регистрация: 11.09.2021
Сообщений: 578
10.12.2023, 23:33  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
... Так себе.
Не безопасно.
Лучше в ресурсы добавить локатор со свойствами для студента и интерфейса сохранения данных.
Из CB задать значения свойствам. А в XAML можно привязываться к ним.
Что такое СВ?

Добавлено через 5 минут
Элд Хасп,

Как должен выглядеть класс модель (Student)?
Вариант-1
C#
1
2
3
4
5
6
public class Student2
{
        public int Id { get; set; }        
        public string FirstName { get; set; }
        public string LastName { get; set; }        
}
Вариант-2
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class Student : BaseVM
    {   
 
        public int _id;
        public int Id
        {
            get { return _id; }
            set 
            {
                _id = value;
                RaisePropertyChanged(nameof(Id));
            }
        }
 
        public string _firstName;
        public string FirstName
        {
            get { return _firstName; }
            set 
            {
                _firstName = value;
                RaisePropertyChanged(nameof(FirstName));
            }
        }
 
 
        public string _lastName;
        public string LastName
        {
            get { return _lastName; }
            set 
            { 
                _lastName = value;
                RaisePropertyChanged(nameof(LastName));
            }
        }
       
    }
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16125 / 11249 / 2888
Регистрация: 21.04.2018
Сообщений: 33,082
Записей в блоге: 2
10.12.2023, 23:50
Цитата Сообщение от dev3214 Посмотреть сообщение
Что такое СВ?
Code Behind

Цитата Сообщение от dev3214 Посмотреть сообщение
Как должен выглядеть класс модель (Student)?
На уровне обмена с Моделью - DTO.
На уровне взаимодействия с View - зависит от необходимости изменять свойства Student из кода Шарпа.
Я предпочитаю реализовывать такие задачи без лишних сущностей, используя те же DTO, что и для обмена с Моделью.
Если нужно изменить свойства такого DTO из Шарпа, то произвожу замену экземпляра целиком.
В крайнем случае использую PropertyDescriptor.
Вот мой хелпер для этого:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
using System;
using System.Collections.Generic;
using System.ComponentModel;
 
namespace CommonCore.Helpers
{
    public static class PropertyDescriptorHelper
    {
        private static readonly Dictionary<Type, PropertyDescriptorCollection> types = new();
 
        private static PropertyDescriptorCollection GetProperties(Type targetType)
        {
            if (!types.TryGetValue(targetType, out var properties))
            {
                properties = TypeDescriptor.GetProperties(targetType);
                types.Add(targetType, properties);
            }
            return properties;
        }
 
        public static void SetValue<T>(this T target, string propertyName, object value)
            where T : class
        {
            GetProperties(target.GetType())[propertyName].SetValue(target, value);
        }
        public static void SetValue<T>(this T target, PropertyDescriptor propertyDescriptor, object value)
            where T : class
        {
            propertyDescriptor.SetValue(target, value);
        }
 
        public static object GetValue<T>(this T target, string propertyName)
            where T : class
        {
            return GetProperties(target.GetType())[propertyName].GetValue(target);
        }
        public static object GetValue<T>(this T target, PropertyDescriptor propertyDescriptor)
            where T : class
        {
            return propertyDescriptor.GetValue(target);
        }
    }
}
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
10.12.2023, 23:50
Помогаю со студенческими работами здесь

Редактирование односвязного/двусвязного списка через DataGrid
Есть у меня коллекция, которую я решил реализовать через односвязный список (изменение одного элемента по цепочке вызывает обновление всех...

Редактирование данных прямо в DataGrid
Здравствуйте, нужна помощь, нужно сделать так, чтобы можно было редактировать данные прямо в DataGrid, после чего нажать кнопку...

DataGrid - редактирование с сохранением в Базу данных
Есть База Данных MS Access и в ней таблица. Эта таблица выведена через DataGrid. Уже есть код который заносит туда данные из TextBox, а...

DataGrid, редактирование данных прямо в таблице
Есть Datagrid с recordset-ом из нескольких баз, можно ли удалять, обновлять, редактировать прямо в таблице и как? Заранее благодарна

Редактирование данных в DataGrid посредством CheckBox
Добрый вечер. Нашел такой пример, для редактирования данных с помощью DataGrid. Но мне нужно редактировать колонку с CheckBox. Не пойму...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru