powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Как правильнее всего сохранить изменённую строку в DataGrid?
20 сообщений из 20, страница 1 из 1
Как правильнее всего сохранить изменённую строку в DataGrid?
    #39544952
хорошо я согласен
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
EntityFrameworkCore
WPF
.Net 4

Есть БД SQLite. С помощью SQLite Toolbox я создал кучу POCO-классов, каждый из которых соответствует таблице в БД.
Во ViewModel создал
Код: c#
1.
ObservableCollection<DBPeople> People {...}


В том же модуле в конструкторе подписался на CollectionChanged. Поэтому добавление и удаление строк работает на ура: удаляю из DataGrid, у меня срабатывает обработчик события CollectionChanged.
А вот когда я меняю значение конкретной ячейки, информирования нет никакого. Хотя в отладке смотрю - действительно поменялось.

Теоретически ответ очевиден - DBPeople нужно переделывать в InotifyPropertyChanged.
Практически - мне что, все POCO классы переделывать? В каждом из них полей {get;set;} по 10 штук, мне ещё к ним добавлять к каждому вызов PropertyChanged и плюс дублировать эти же поля, но делать их локальными?
Или это как-то по-человечески делается?

Код: 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.
public partial class DBPeople
{
    public DBPeople()
    {
        IndiK = new HashSet<IndiK>();
        IndiT = new HashSet<IndiT>();
        TeamK = new HashSet<TeamK>();
        TeamT = new HashSet<TeamT>();
        PartInT = new HashSet<PartInT>();
        TToParts = new HashSet<TToParts>();
    }
    //Отсюда
    public long Id { get; set; }
    public string RegNum { get; set; }
    public string Surname { get; set; }
    public string Name { get; set; }
    public string Patronimic { get; set; }
    public string Birthdate { get; set; }
    public long? SexId { get; set; }
    public long? PassId { get; set; }
    public long? OrganizationId { get; set; }
    public long? RegionId { get; set; }
    //до сюда нужно всё продублировать, сделать private, добавить PropertyChanged - и так для всех нескольких десятков таблиц?

    public virtual ICollection<IndiK> IndiK { get; set; }
    public virtual ICollection<IndiT> IndiT { get; set; }
    public virtual ICollection<TeamK> TeamK { get; set; }
    public virtual ICollection<TeamT> TeamT { get; set; }
    public virtual ICollection<PartInT> PartInT { get; set; }
    public virtual ICollection<TToParts> TToParts { get; set; }
    public virtual Passes Pass { get; set; }
    public virtual Organizations Organization { get; set; }
    public virtual Regions Region { get; set; }
    public virtual Sexes Sex { get; set; }
}



Могу, конечно, прицепиться к событиям в гриде. Тогда мне придётся обрабатывать их в code-behind моего View. Получается, что добавлление/удаление я обрабатываю в ViewModel, а изменение - в View. Тоже криво.
Как правильно это делается в MVVM?
...
Рейтинг: 0 / 0
Как правильнее всего сохранить изменённую строку в DataGrid?
    #39544995
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
хорошо я согласенМогу, конечно, прицепиться к событиям в гриде. Тогда мне придётся обрабатывать их в code-behind моего View. Получается, что добавлление/удаление я обрабатываю в ViewModel, а изменение - в View. Тоже криво.
Как правильно это делается в MVVM?
В общем случае по MVVM, вы события передаёте в слой БЛ, т.е. в VM.
Если у вас авиоматический биндинг не работает на изменение.
...
Рейтинг: 0 / 0
Как правильнее всего сохранить изменённую строку в DataGrid?
    #39545011
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
хорошо я согласен,
Т.е. типа такого
viewModelPeople.Change (people);
...
Рейтинг: 0 / 0
Как правильнее всего сохранить изменённую строку в DataGrid?
    #39545121
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
хорошо я согласенИли это как-то по-человечески делается?
У меня это делается как-то так:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
public class Person: WxBaseModel
{
  public string Name
  {
    get { return Get(()=>Name); }
    set { Set(()=>Name, value); }
  }
}


Ноги у такого решения растут отсюда . Оно еще и позволяет, например, декларативно (с помощью атрибутов) описывать зависимости между свойствами и командами (когда при изменении одного свойства выдаются оповещения подписчикам об изменении других свойств, или вызываются CanExecuteChanged у команд).
Многие прибегают к использованию IL weaving - с помощью PostSharp, например. Примеры таких решений см., например, здесь: http://justinangel.net/AutomagicallyImplementingINotifyPropertyChanged , http://softblog.violet-tape.ru/2011/07/16/hateful-inotifypropertychanged/ .
...
Рейтинг: 0 / 0
Как правильнее всего сохранить изменённую строку в DataGrid?
    #39546463
хорошо я согласен
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо за ответы! Но нет.
Решения "Petro123" всё же заставляют делать разную логику для добавления и изменения строки, а я бы хотел отслеживать изменения данных самостоятельно.
Решение "Сон Веры Павловны" заставляет делать то, чего я не хотел - менять всю огромную кучу (предположим, из сотни, грубо говоря) классов, нагенерированных с помощью SQLite Tools, добавляя INotifyPropertyChanged.

Я продолжил поиски и понял, что рыть надо было в направлении
Код: c#
\r\npeopleview = (CollectionView)new CollectionViewSource { Source = People }.View;\r\n
\r\n
И цеплять уже грид к peopleview
...
Рейтинг: 0 / 0
Как правильнее всего сохранить изменённую строку в DataGrid?
    #39546498
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
хорошо я согласеннагенерированных
Всё индивидуально и зависит от проекта.
Каждая форма выписывается художником-программистом индивидуально. Что декларативно, что нет.
хорошо я согласенИ цеплять уже грид к peopleview
Чуть подробнее. ..
...
Рейтинг: 0 / 0
Как правильнее всего сохранить изменённую строку в DataGrid?
    #39546532
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
хорошо я согласен ,

peopleview = (CollectionView)new CollectionViewSource { Source = People }.View;
трудно сказать, где это реально может быть нужным :)
приводит лучше не к абстрактному классу CollectionView, А к интерфейсу ICollectionView.
создавать инстанс CollectionViewSource нет ни какой нужны, у этого класса есть статический метод GetDefaultView(). И нужен он для работы с представлениями коллекций из XAML.
1 пост ни как не связан с последним.
Ваша проблема решается элементарным и классическим способом, для этого нужно нормально реализовать свойства с которыми вы связывайте ячейки. Так же у DataGrid есть события BeginEdit, EndEdit, где в качестве аргументов передается, что, где, когда и т.д.

Вы высасывайте проблему из пальца, только потому, что вам лень нормально прописать все свойства классов и модели представления. Советую вам почитать про снипеты и шаблоны.

В заключении. Я вижу класс PeopleBD, и его название говорит мне, что это класс модели данных. Той модели о которой View ничего знать не должна, если вы используйте шаблон MVVVM. Именно от сюда и растут ноги вашей проблемы. Между этим классом и классом формы должна быть прокладка в виде VM. На первых порах кажется, что это избыточность и приведет только к торможение, но без этого лучше даже не начинать
...
Рейтинг: 0 / 0
Как правильнее всего сохранить изменённую строку в DataGrid?
    #39546569
хорошо я согласен
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman Mejtesтолько потому, что вам лень нормально прописать
не, мне не лень даже создать целую фабрику классов, если это понадобится. Проект, который я делаю, нужен мне прежде всего для того, чтобы понять, как всё делать правильно в рамках концепции MVVM. Перечитал кучу литературы, пересмотрел несколько видеоуроков типа Lynda.com, теперь осваиваю на практике. Конечно, не всё задержалось в голове, поэтому я перешёл к практике.
Будь мне лень и надо было бы сделать по-быстрее - я б забил на такие мелочи и делал первым пришедшим мне в голову способом.

Упомянутый код
Код: c#
1.
peopleview = (CollectionView)new CollectionViewSource { Source = People }.View;


я прописывал именно в модуле ViewModel класса окна. Я считал, что та "сотня" классов (у меня их 6 на самом деле, но я прикидываю, как бы я делал для большой БД) - это уже Model.
Значит, как я понимаю, в таком случае самым правильным решением будет именно наследование всех от от INotifyPropertyChanged. Ну или от некоторого общего класса, который унаследован от этого интерфейса (а это уже детали).

Roman MejtesЯ вижу класс PeopleBD, и его название говорит мне, что это класс модели данных. Той модели о которой View ничего знать не должна, если вы используйте шаблон MVVVM. Именно от сюда и растут ноги вашей проблемы. Между этим классом и классом формы должна быть прокладка в виде VM.
Вот я немного недопонимаю, если PeopleBD - модель, то как должен выглядить VM, если там один-в-один те же самые поля? Я вообще-то собирался столбцы грида байндить к полям PeopleBD.

Вообще, я статью находил, где какой-то американец описывал, что самое крутое - это забайндить DataGrid с peopleview (который является View от People, который, в свою очередь, ObservableCollection<DBPeople>), а мы подписываемся на события не грида, а этого самого peopleview и уже реагируем на них.
...
Рейтинг: 0 / 0
Как правильнее всего сохранить изменённую строку в DataGrid?
    #39546574
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
хорошо я согласенправильно в рамках концепции MVVM.
Надо было такую тему и создать.
Ты всю тему забил лишней инфой про генерацию 100таблиц.
...
Рейтинг: 0 / 0
Как правильнее всего сохранить изменённую строку в DataGrid?
    #39546576
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
хорошо я согласенто как должен выглядить VM, если там один-в-один те же самые поля?
Начни с демки MVVM и новой темы.
Она не про грид вообще.
...
Рейтинг: 0 / 0
Как правильнее всего сохранить изменённую строку в DataGrid?
    #39546584
хорошо я согласен
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123хорошо я согласенто как должен выглядить VM, если там один-в-один те же самые поля?
Начни с демки MVVM и новой темы.
Она не про грид вообще.
Не, прога, которую я пишу, полезная.
Я пытаюсь увязать редактируемые грид с БД. Во всех проектах, что я находил в сети (github и пр.), грид не был редактируемым. Решил у знатоков узнать, как организовывается передача в БД инфы о том, что строка в гриде была отредактирована.
...
Рейтинг: 0 / 0
Как правильнее всего сохранить изменённую строку в DataGrid?
    #39546635
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
хорошо я согласен,
Я и говорю. Ты сразу совместил ПервыйВмиреРедакторГрид и правильно по MVVM.
Сложно тебе будет. Вот и всё.
Ещё бизнес логику добавь, валидацию и виртуализацию.
Удачи!
...
Рейтинг: 0 / 0
Как правильнее всего сохранить изменённую строку в DataGrid?
    #39547097
хорошо я согласен
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ключевой вопрос, который закроет эту тему:
Вот простенькая законченная программа на гитхабе .

До mvvm там далеко, но есть там одна штука, которая работает по волшебству:
На форме есть datagrid и list , отображающие одну и ту же информацию.

Не могу понять, каким образом list узнаёт от datagrid о том, что в datagrid изменились ячейки, отображая все изменения синхронно (вернее, как только по факту окончания редактирования строки)?

Там прямо непосредственно в конструкторе класса окна прописано:
Код: c#
1.
2.
3.
4.
5.
6.
            products = new Products();
            productsToSearch = new ProductsToSearch();
            cart = new Cart();
            view = (CollectionView)new CollectionViewSource { Source = products }.View;
            lstPersons.ItemsSource = view;
            view2 = (CollectionView)new CollectionViewSource { Source = products }.View;


Никаких событий ни у листа, ни у грида нет.

При этом что из себя представляет Products:
Код: c#
1.
public class Products : ObservableCollection<Product>


а Product не является унаследованным от INotifyPropertyChanged, обычный, ни от чего не унаследованный класс, хотя lstPersons сразу узнаёт обо всех изменениях полей этого класса. Как такое возможно?

Как самому узнать об изменениях в Products таким же образом, каким это делает этот list без применения упомянутого интерфейса? Колдовство просто какое-то
...
Рейтинг: 0 / 0
Как правильнее всего сохранить изменённую строку в DataGrid?
    #39547118
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
хорошо я согласенНе могу понять, каким образом list узнаёт от datagrid о том, что в datagrid изменились ячейки, отображая все изменения синхронно (вернее, как только по факту окончания редактирования строки)?
Об это узнает не list, а экземпляр ICollectionView, к кторому биндится DataGrid. Внутренняя реализация ICollectionView ловит изменения, и транслирует их в underlying source.

хорошо я согласенКак самому узнать об изменениях в Products таким же образом, каким это делает этот list без применения упомянутого интерфейса? Колдовство просто какое-то
Никак. И list об этом никак не узнает, см. выше. И событий у ICollectionView, оповещающих об изменении вотдельном элементе, нет. Поэтому без реализации INPC - никак.
...
Рейтинг: 0 / 0
Как правильнее всего сохранить изменённую строку в DataGrid?
    #39547141
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
хорошо я согласен,

за это отвечает ICollectionView и класс Selector, который унаследован как ListBox, так и DataGrid
https://msdn.microsoft.com/ru-ru/library/system.windows.controls.primitives.selector.issynchronizedwithcurrentitem(v=vs.110).aspx
Отключить это можно либо так. Либо создав 2 разных представления для этого источника.
В соседней теме про это писали дней 5 назад
...
Рейтинг: 0 / 0
Как правильнее всего сохранить изменённую строку в DataGrid?
    #39547522
refreg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры Павловныхорошо я согласенНе могу понять, каким образом list узнаёт от datagrid о том, что в datagrid изменились ячейки, отображая все изменения синхронно (вернее, как только по факту окончания редактирования строки)?
Об это узнает не list, а экземпляр ICollectionView, к кторому биндится DataGrid. Внутренняя реализация ICollectionView ловит изменения, и транслирует их в underlying source.Может, все проще: коллекция для списка и коллекция для датагрид ссылаются на одни и те же объекты (элементы исходной коллекции).
...
Рейтинг: 0 / 0
Как правильнее всего сохранить изменённую строку в DataGrid?
    #39547538
хорошо я согласен
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman MejtesОтключить это можно либо так. Либо создав 2 разных представления для этого источника.
в приведённом мной примере два представления - view для списка и view2 для датагрида. Тем не менее, как только в гриде завершается редактирование строки, данные передаются в обычный POCO с данными (и без INPC), а оттуда возвращаются в list и он их тут же обновляет. Как узнаёт о наличии изменений мне по-прежнему не понятно, к сожалению.
Потому что обычно для того, чтобы компонент узнал о том, что в POCO-классе изменились данные, нужно реализовать INPC. А тут как-то вот просто взял, да узнал.
...
Рейтинг: 0 / 0
Как правильнее всего сохранить изменённую строку в DataGrid?
    #39547544
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я понял о чем говорит автор :)
вот пример:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
<Window x:Class="WpfApp4.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:WpfApp4"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <local:MainModel x:Key="MainModel"/>
    </Window.Resources>
    <Grid DataContext="{StaticResource MainModel}">
        <StackPanel>
            <TextBox Text="{Binding Value}"/>
            <TextBox Text="{Binding Value}"/>
        </StackPanel>
    </Grid>
</Window>


Код: c#
1.
2.
3.
4.
5.
6.
7.
namespace WpfApp4
{
    public class MainModel
    {
        public string Value { set; get; } = "Test value";
    }
}


в этом примере видно, что класс MainModel от INPC не унаследован, но если изменить значение в TextBox1, оно изменится в TextBox2.
Происходит это из-за во внутренней реализации Binding'а. Когда значение задается из View в ViewModel (от Target к Source), оно автоматически обновляется для всех привязок к этому объекту и по заданному свойству (в зависимости от ограничений связывания, конечно же)
Об этом читал в какой то книжке :) не помню какой, но это есть и это работает, проверено
...
Рейтинг: 0 / 0
Как правильнее всего сохранить изменённую строку в DataGrid?
    #39547564
хорошо я согласен
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Как правильнее всего сохранить изменённую строку в DataGrid?
    #39547566
хорошо я согласен
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
"Roman Mejtes", спасибо!)) груз неопределённости рухнул с плеч.
...
Рейтинг: 0 / 0
20 сообщений из 20, страница 1 из 1
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Как правильнее всего сохранить изменённую строку в DataGrid?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]