|
Как правильнее всего сохранить изменённую строку в DataGrid?
|
|||
---|---|---|---|
#18+
EntityFrameworkCore WPF .Net 4 Есть БД SQLite. С помощью SQLite Toolbox я создал кучу POCO-классов, каждый из которых соответствует таблице в БД. Во ViewModel создал Код: c# 1.
В том же модуле в конструкторе подписался на 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.
Могу, конечно, прицепиться к событиям в гриде. Тогда мне придётся обрабатывать их в code-behind моего View. Получается, что добавлление/удаление я обрабатываю в ViewModel, а изменение - в View. Тоже криво. Как правильно это делается в MVVM? ... |
|||
:
Нравится:
Не нравится:
|
|||
31.10.2017, 00:13 |
|
Как правильнее всего сохранить изменённую строку в DataGrid?
|
|||
---|---|---|---|
#18+
хорошо я согласенМогу, конечно, прицепиться к событиям в гриде. Тогда мне придётся обрабатывать их в code-behind моего View. Получается, что добавлление/удаление я обрабатываю в ViewModel, а изменение - в View. Тоже криво. Как правильно это делается в MVVM? В общем случае по MVVM, вы события передаёте в слой БЛ, т.е. в VM. Если у вас авиоматический биндинг не работает на изменение. ... |
|||
:
Нравится:
Не нравится:
|
|||
31.10.2017, 07:47 |
|
Как правильнее всего сохранить изменённую строку в DataGrid?
|
|||
---|---|---|---|
#18+
хорошо я согласен, Т.е. типа такого viewModelPeople.Change (people); ... |
|||
:
Нравится:
Не нравится:
|
|||
31.10.2017, 08:51 |
|
Как правильнее всего сохранить изменённую строку в DataGrid?
|
|||
---|---|---|---|
#18+
хорошо я согласенИли это как-то по-человечески делается? У меня это делается как-то так: Код: c# 1. 2. 3. 4. 5. 6. 7. 8.
Ноги у такого решения растут отсюда . Оно еще и позволяет, например, декларативно (с помощью атрибутов) описывать зависимости между свойствами и командами (когда при изменении одного свойства выдаются оповещения подписчикам об изменении других свойств, или вызываются CanExecuteChanged у команд). Многие прибегают к использованию IL weaving - с помощью PostSharp, например. Примеры таких решений см., например, здесь: http://justinangel.net/AutomagicallyImplementingINotifyPropertyChanged , http://softblog.violet-tape.ru/2011/07/16/hateful-inotifypropertychanged/ . ... |
|||
:
Нравится:
Не нравится:
|
|||
31.10.2017, 11:49 |
|
Как правильнее всего сохранить изменённую строку в DataGrid?
|
|||
---|---|---|---|
#18+
Спасибо за ответы! Но нет. Решения "Petro123" всё же заставляют делать разную логику для добавления и изменения строки, а я бы хотел отслеживать изменения данных самостоятельно. Решение "Сон Веры Павловны" заставляет делать то, чего я не хотел - менять всю огромную кучу (предположим, из сотни, грубо говоря) классов, нагенерированных с помощью SQLite Tools, добавляя INotifyPropertyChanged. Я продолжил поиски и понял, что рыть надо было в направлении Код: c#
И цеплять уже грид к peopleview ... |
|||
:
Нравится:
Не нравится:
|
|||
02.11.2017, 02:45 |
|
Как правильнее всего сохранить изменённую строку в DataGrid?
|
|||
---|---|---|---|
#18+
хорошо я согласеннагенерированных Всё индивидуально и зависит от проекта. Каждая форма выписывается художником-программистом индивидуально. Что декларативно, что нет. хорошо я согласенИ цеплять уже грид к peopleview Чуть подробнее. .. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.11.2017, 07:17 |
|
Как правильнее всего сохранить изменённую строку в DataGrid?
|
|||
---|---|---|---|
#18+
хорошо я согласен , peopleview = (CollectionView)new CollectionViewSource { Source = People }.View; трудно сказать, где это реально может быть нужным :) приводит лучше не к абстрактному классу CollectionView, А к интерфейсу ICollectionView. создавать инстанс CollectionViewSource нет ни какой нужны, у этого класса есть статический метод GetDefaultView(). И нужен он для работы с представлениями коллекций из XAML. 1 пост ни как не связан с последним. Ваша проблема решается элементарным и классическим способом, для этого нужно нормально реализовать свойства с которыми вы связывайте ячейки. Так же у DataGrid есть события BeginEdit, EndEdit, где в качестве аргументов передается, что, где, когда и т.д. Вы высасывайте проблему из пальца, только потому, что вам лень нормально прописать все свойства классов и модели представления. Советую вам почитать про снипеты и шаблоны. В заключении. Я вижу класс PeopleBD, и его название говорит мне, что это класс модели данных. Той модели о которой View ничего знать не должна, если вы используйте шаблон MVVVM. Именно от сюда и растут ноги вашей проблемы. Между этим классом и классом формы должна быть прокладка в виде VM. На первых порах кажется, что это избыточность и приведет только к торможение, но без этого лучше даже не начинать ... |
|||
:
Нравится:
Не нравится:
|
|||
02.11.2017, 09:49 |
|
Как правильнее всего сохранить изменённую строку в DataGrid?
|
|||
---|---|---|---|
#18+
Roman Mejtesтолько потому, что вам лень нормально прописать не, мне не лень даже создать целую фабрику классов, если это понадобится. Проект, который я делаю, нужен мне прежде всего для того, чтобы понять, как всё делать правильно в рамках концепции MVVM. Перечитал кучу литературы, пересмотрел несколько видеоуроков типа Lynda.com, теперь осваиваю на практике. Конечно, не всё задержалось в голове, поэтому я перешёл к практике. Будь мне лень и надо было бы сделать по-быстрее - я б забил на такие мелочи и делал первым пришедшим мне в голову способом. Упомянутый код Код: c# 1.
я прописывал именно в модуле ViewModel класса окна. Я считал, что та "сотня" классов (у меня их 6 на самом деле, но я прикидываю, как бы я делал для большой БД) - это уже Model. Значит, как я понимаю, в таком случае самым правильным решением будет именно наследование всех от от INotifyPropertyChanged. Ну или от некоторого общего класса, который унаследован от этого интерфейса (а это уже детали). Roman MejtesЯ вижу класс PeopleBD, и его название говорит мне, что это класс модели данных. Той модели о которой View ничего знать не должна, если вы используйте шаблон MVVVM. Именно от сюда и растут ноги вашей проблемы. Между этим классом и классом формы должна быть прокладка в виде VM. Вот я немного недопонимаю, если PeopleBD - модель, то как должен выглядить VM, если там один-в-один те же самые поля? Я вообще-то собирался столбцы грида байндить к полям PeopleBD. Вообще, я статью находил, где какой-то американец описывал, что самое крутое - это забайндить DataGrid с peopleview (который является View от People, который, в свою очередь, ObservableCollection<DBPeople>), а мы подписываемся на события не грида, а этого самого peopleview и уже реагируем на них. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.11.2017, 11:00 |
|
Как правильнее всего сохранить изменённую строку в DataGrid?
|
|||
---|---|---|---|
#18+
хорошо я согласенправильно в рамках концепции MVVM. Надо было такую тему и создать. Ты всю тему забил лишней инфой про генерацию 100таблиц. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.11.2017, 11:10 |
|
Как правильнее всего сохранить изменённую строку в DataGrid?
|
|||
---|---|---|---|
#18+
хорошо я согласенто как должен выглядить VM, если там один-в-один те же самые поля? Начни с демки MVVM и новой темы. Она не про грид вообще. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.11.2017, 11:14 |
|
Как правильнее всего сохранить изменённую строку в DataGrid?
|
|||
---|---|---|---|
#18+
Petro123хорошо я согласенто как должен выглядить VM, если там один-в-один те же самые поля? Начни с демки MVVM и новой темы. Она не про грид вообще. Не, прога, которую я пишу, полезная. Я пытаюсь увязать редактируемые грид с БД. Во всех проектах, что я находил в сети (github и пр.), грид не был редактируемым. Решил у знатоков узнать, как организовывается передача в БД инфы о том, что строка в гриде была отредактирована. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.11.2017, 11:28 |
|
Как правильнее всего сохранить изменённую строку в DataGrid?
|
|||
---|---|---|---|
#18+
хорошо я согласен, Я и говорю. Ты сразу совместил ПервыйВмиреРедакторГрид и правильно по MVVM. Сложно тебе будет. Вот и всё. Ещё бизнес логику добавь, валидацию и виртуализацию. Удачи! ... |
|||
:
Нравится:
Не нравится:
|
|||
02.11.2017, 12:18 |
|
Как правильнее всего сохранить изменённую строку в DataGrid?
|
|||
---|---|---|---|
#18+
Ключевой вопрос, который закроет эту тему: Вот простенькая законченная программа на гитхабе . До mvvm там далеко, но есть там одна штука, которая работает по волшебству: На форме есть datagrid и list , отображающие одну и ту же информацию. Не могу понять, каким образом list узнаёт от datagrid о том, что в datagrid изменились ячейки, отображая все изменения синхронно (вернее, как только по факту окончания редактирования строки)? Там прямо непосредственно в конструкторе класса окна прописано: Код: c# 1. 2. 3. 4. 5. 6.
Никаких событий ни у листа, ни у грида нет. При этом что из себя представляет Products: Код: c# 1.
а Product не является унаследованным от INotifyPropertyChanged, обычный, ни от чего не унаследованный класс, хотя lstPersons сразу узнаёт обо всех изменениях полей этого класса. Как такое возможно? Как самому узнать об изменениях в Products таким же образом, каким это делает этот list без применения упомянутого интерфейса? Колдовство просто какое-то ... |
|||
:
Нравится:
Не нравится:
|
|||
03.11.2017, 02:43 |
|
Как правильнее всего сохранить изменённую строку в DataGrid?
|
|||
---|---|---|---|
#18+
хорошо я согласенНе могу понять, каким образом list узнаёт от datagrid о том, что в datagrid изменились ячейки, отображая все изменения синхронно (вернее, как только по факту окончания редактирования строки)? Об это узнает не list, а экземпляр ICollectionView, к кторому биндится DataGrid. Внутренняя реализация ICollectionView ловит изменения, и транслирует их в underlying source. хорошо я согласенКак самому узнать об изменениях в Products таким же образом, каким это делает этот list без применения упомянутого интерфейса? Колдовство просто какое-то Никак. И list об этом никак не узнает, см. выше. И событий у ICollectionView, оповещающих об изменении вотдельном элементе, нет. Поэтому без реализации INPC - никак. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.11.2017, 07:30 |
|
Как правильнее всего сохранить изменённую строку в DataGrid?
|
|||
---|---|---|---|
#18+
хорошо я согласен, за это отвечает ICollectionView и класс Selector, который унаследован как ListBox, так и DataGrid https://msdn.microsoft.com/ru-ru/library/system.windows.controls.primitives.selector.issynchronizedwithcurrentitem(v=vs.110).aspx Отключить это можно либо так. Либо создав 2 разных представления для этого источника. В соседней теме про это писали дней 5 назад ... |
|||
:
Нравится:
Не нравится:
|
|||
03.11.2017, 08:39 |
|
Как правильнее всего сохранить изменённую строку в DataGrid?
|
|||
---|---|---|---|
#18+
Сон Веры Павловныхорошо я согласенНе могу понять, каким образом list узнаёт от datagrid о том, что в datagrid изменились ячейки, отображая все изменения синхронно (вернее, как только по факту окончания редактирования строки)? Об это узнает не list, а экземпляр ICollectionView, к кторому биндится DataGrid. Внутренняя реализация ICollectionView ловит изменения, и транслирует их в underlying source.Может, все проще: коллекция для списка и коллекция для датагрид ссылаются на одни и те же объекты (элементы исходной коллекции). ... |
|||
:
Нравится:
Не нравится:
|
|||
03.11.2017, 15:48 |
|
Как правильнее всего сохранить изменённую строку в DataGrid?
|
|||
---|---|---|---|
#18+
Roman MejtesОтключить это можно либо так. Либо создав 2 разных представления для этого источника. в приведённом мной примере два представления - view для списка и view2 для датагрида. Тем не менее, как только в гриде завершается редактирование строки, данные передаются в обычный POCO с данными (и без INPC), а оттуда возвращаются в list и он их тут же обновляет. Как узнаёт о наличии изменений мне по-прежнему не понятно, к сожалению. Потому что обычно для того, чтобы компонент узнал о том, что в POCO-классе изменились данные, нужно реализовать INPC. А тут как-то вот просто взял, да узнал. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.11.2017, 16:14 |
|
Как правильнее всего сохранить изменённую строку в DataGrid?
|
|||
---|---|---|---|
#18+
я понял о чем говорит автор :) вот пример: Код: xml 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18.
Код: c# 1. 2. 3. 4. 5. 6. 7.
в этом примере видно, что класс MainModel от INPC не унаследован, но если изменить значение в TextBox1, оно изменится в TextBox2. Происходит это из-за во внутренней реализации Binding'а. Когда значение задается из View в ViewModel (от Target к Source), оно автоматически обновляется для всех привязок к этому объекту и по заданному свойству (в зависимости от ограничений связывания, конечно же) Об этом читал в какой то книжке :) не помню какой, но это есть и это работает, проверено ... |
|||
:
Нравится:
Не нравится:
|
|||
03.11.2017, 16:26 |
|
Как правильнее всего сохранить изменённую строку в DataGrid?
|
|||
---|---|---|---|
#18+
... |
|||
:
Нравится:
Не нравится:
|
|||
03.11.2017, 16:52 |
|
|
start [/forum/topic.php?fid=21&msg=39547522&tid=1440476]: |
0ms |
get settings: |
9ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
171ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
57ms |
get tp. blocked users: |
1ms |
others: | 14ms |
total: | 284ms |
0 / 0 |