|
Атрибуты свойств модели - через модель представления - привязать к представлению - как?
|
|||
---|---|---|---|
#18+
WPF, MVVM. В модели есть, например, класс: Код: c# 1. 2. 3. 4. 5. 6. 7. 8.
В модели представления: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18.
В представлении хочу сделать что-то типа этого: Код: xml 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
Т. е. хочу "протащить" значения атрибутов каждого свойства из модели в представления. Как сделать? Не создавать же в модели представления для каждого свойства модели ещё и "обвязку" в виде свойств для каждого свойства каждого атрибута? Пробовал в гугле искать на английском примерно то же, что в названии темы - вообще ноль. Такое ощущение, что я что-то делаю не так и никто такой задачей не задавался. Кстати, везде в примерах с атрибутами их задают сразу для модели представления и привязывают эти атрибуты как-то (через конвертеры, например) к представлению. Но чтобы как я хочу - ничего нет. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.01.2013, 19:29 |
|
Атрибуты свойств модели - через модель представления - привязать к представлению - как?
|
|||
---|---|---|---|
#18+
Последняя привязка не к Name, а к Description. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.01.2013, 19:30 |
|
Атрибуты свойств модели - через модель представления - привязать к представлению - как?
|
|||
---|---|---|---|
#18+
я бы конвертер написал ... |
|||
:
Нравится:
Не нравится:
|
|||
26.01.2013, 20:09 |
|
Атрибуты свойств модели - через модель представления - привязать к представлению - как?
|
|||
---|---|---|---|
#18+
Тут вот ещё в чём штука. Те три текстовых поля в XAML'e объединены в юзер контрол, который байндится к экземпляру MyVM. Поэтому первый текстблок (там текстбокс должен быть вообще-то, но неважно) я могу сразу привязать к MyVMProperty, что и сделано. А остальные - через конвертер, как вы и сказали. Но тут сложности у меня возникли. По идее, надо из конвертера достать свойства атрибутов свойств МОДЕЛИ (во сколько вложенностей!). Т. е. надо сделать так, как я понимаю: 1) в конвертер передать: а) тип модели; б) имя свойства модели; в) тип атрибута свойства модели; г) имя свойства атрибута указанного свойства модели (само по себе уже некисло!); 2) в конвертере: а) из типа модели достать её свойство указанного имени; б) узнать тип этого свойства; в) у узнанного типа свойства модели достать атрибут указанного типа; г) у этого утрибута достать свойство указаного имени и вернуть его. Я правильно всё понимаю? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.01.2013, 21:02 |
|
Атрибуты свойств модели - через модель представления - привязать к представлению - как?
|
|||
---|---|---|---|
#18+
Что-то много ручной писанины получится. Получается, я в представлении пишу, как устроена модель (не модель представления даже, а модель) - имена свойств, их типы, имена свойств атрибутов и прочее. Получается сильная связь. Неужели нет простого способа, если хочешь свойства свойств модели показать в представлении? Ну вроде бы распространённая задача: есть группа настроек, есть настройки в этой группе, у каждой настройки описание и название. Настройку помещяю в свойство объекта группы настроек, а описание и название - в метаданные этого СВОЙСТВА (т. е. в атрибуты настройки). Это всё модель. В модели представления представляю ТОЛЬКО саму настройку, без её метаданных - т. е. НЕ завожу ещё кучу полей, каждое из которых представляет КАЖДОЕ свойство КАЖДОГО атрибута КАЖДОГО свойства модели ("свойства" два раза повторяется - это не ошибка). Как достать значения свойств этих атрибутов из модели в представлении? Если заводить свойства для свойств атрибутов модели, то получится вот что. Положим, у меня 2 свойства в модели. У каждого свойства по 2 атрибута. У каждого из этих двух атрибутов по 2 своих свойства. Тогда в модели представления мне надо завести 2 свойства, представляющих свойства модели, и 2*2*2=8 свойств, представляющих метаданные свойств модели! Это же неправильно! ... |
|||
:
Нравится:
Не нравится:
|
|||
26.01.2013, 21:09 |
|
Атрибуты свойств модели - через модель представления - привязать к представлению - как?
|
|||
---|---|---|---|
#18+
Всё было бы проще, если бы модель представления унаследовала метаданные модели (все эти атрибуты и их значения). Только без собственно наследования. Можно это как-то сделать? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.01.2013, 21:35 |
|
Атрибуты свойств модели - через модель представления - привязать к представлению - как?
|
|||
---|---|---|---|
#18+
Т. е. я хочу, чтобы у каждого свойства модели представления появились такие же атрибуты, как у соответствующих свойств модели, но чтобы я руками их сам не вбивал, а чтобы они как-то сами там оказались. Как это сделать в коде? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.01.2013, 21:37 |
|
Атрибуты свойств модели - через модель представления - привязать к представлению - как?
|
|||
---|---|---|---|
#18+
Кстати, по тому, что я написал, уже понятно, что конвертер не подходит. Мне надо передать имя свойства модели и имя своства атрибута модели - уже два параметра, в то время как у конвертера он только один. Конвертер со множеством значений (IMultiValueConverter) тоже не подходит, т. к. эти значения - это не параметры. Параметр по-прежнему один, а значения - это свойства привязываемой модели. Т. е., чтобы воспользоваться IMultiValueConverter, надо обернуть каждое свойство модели представления в некий класс со свойствами, которые и будут выступать в качетсве значений IMultiValueConverter. Т. е. целый класс-обёртку городить. Самое разумное было бы - предоставить возможность конвертеру (даже обычному, не надо IMultiValueConverter), принимать множество параметров. Тогда бы я мог туда и имена свойств передать, и их типы. В принципе, я могу это сделать и так, затолкав все эти данные в один параметр-строку с символами-разделителями и распарсив её в конвертере. Но это уже получится, что я борюсь со фреймворком, вместо того, чтобы его использовать. Отсюда вывод, что для того, чего я хочу, создатели фреймворка ничего не предусмотрели - приходится делать свои костыли. Это навело меня на мысль, что не является ли это неправильным подходом - предоставлять метаданные модели в представлении сразу? Может, более правильным будет, когда метаданные модели в модели представления представляются ОБЫЧНЫМИ ДАННЫМИ? Тогда и не надо будет никаких конвертеров - бери и привязывай данные напрямую. Тогда мысль с классом обёрткой была правильная. Т. е. каждое свойство модели представления - это не просто трансляция свойств модели, а объект с полями, представляющими собой собственно свойство модели, плюс метаданные свойства моделит, но уже в виде обычных данных. Как вы считаете? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.01.2013, 23:29 |
|
Атрибуты свойств модели - через модель представления - привязать к представлению - как?
|
|||
---|---|---|---|
#18+
Правильно будет не устраивать подобные мультики из-за трех textbox. Если уж так хочется, то создавай свой контрол, который будет использовать атрибуты свойства. По такому принципу построена dataform ... |
|||
:
Нравится:
Не нравится:
|
|||
27.01.2013, 10:21 |
|
Атрибуты свойств модели - через модель представления - привязать к представлению - как?
|
|||
---|---|---|---|
#18+
user7320Мне надо передать имя свойства модели и имя своства атрибута модели - уже два параметра, в то время как у конвертера он только один. Во-первых, можно не страдать излишним перфекционизмом, и сделать несколько конвертеров под определенный тип модели и атрибута - тогда параметром будет достаточно передать имя поля атрибута. Во-вторых, в данном случае постановка задачи содержит ошибку - никак не задана связь MyVM.MyVMProperty и MyModel.MyProperty - её не вытащить и с помощью reflection. Если перенести атрибут на MyVM.MyVMProperty, то без конвертеров с вхардкоденными моделью/атрибутом задачу можно решить через собственную реализацию MarkupExtension. Примерный вариант можно посмотреть здесь , но у этого примера есть один недастаток: он не позволяет именно в разметке забиндиться на значение поля атрибута. Это решается примерно так: Код: 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.
Тогда в разметке действительно можно будет написать так: Код: xml 1. 2.
Преимущество такого решения перед конвертером в том, что в свойствах MetaDataBindingExtension можно задать всё, что потребуется далее - например, тип атрибута, который далее можно будет контролировать при извлечении атрибутов. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.01.2013, 11:20 |
|
Атрибуты свойств модели - через модель представления - привязать к представлению - как?
|
|||
---|---|---|---|
#18+
user7320Самое разумное было бы - предоставить возможность конвертеру (даже обычному, не надо IMultiValueConverter), принимать множество параметров. Тогда бы я мог туда и имена свойств передать, и их типы. Это, кстати, вполне возможно: Код: 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.
Код: xml 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
... |
|||
:
Нравится:
Не нравится:
|
|||
27.01.2013, 12:34 |
|
Атрибуты свойств модели - через модель представления - привязать к представлению - как?
|
|||
---|---|---|---|
#18+
авторВо-первых, можно не страдать излишним перфекционизмом, и сделать несколько конвертеров под определенный тип модели и атрибута - тогда параметром будет достаточно передать имя поля атрибута. У меня до десяти типов модели, которые надо показывать в интерфейсе (и ещё больше может быть в будущем), плюс атрибуты тоже разные могут использоваться - минимум уже Display и Range. 10х2=20 конвертеров писать, у которых шаблонный код. Нет уж. Мне маленькая простыня во втором вашем посте нравится больше, чем большая в первом. Но всё это меня тревожит вот в чём. Всё, для чего требуются такие простыни кода - это борьба со фреймворком. Разве то, что я хочу - показать в представлении метаданные модели - это так много? Нет удобного средства во фреймворке сделать это? Вроде, это распространённая задача. Получается, что каждый первый, кто сталкивается с этим (а с этим сталкивается, похоже, каждый первый) пишет свою простыню кода на такую распространённую задачу, а создатели фреймворка вот уже десять лет не могут её отшаблонить, хотя всяких ТоСтрингов делают по шестнадцать перегрузов зачем-то? Ладно. У меня относительно второго поста Сон Веры Павловны вопрос - этот класс MetadataParameters надо куда заводить? Получается, что для каждого свойства модели представления надо заводить по одному свойству MetadataParameters? Или придумывать класс, в который помещать одно свойство типа MetadataParameters, а второе - собственно свойство модели? ... |
|||
:
Нравится:
Не нравится:
|
|||
27.01.2013, 15:59 |
|
Атрибуты свойств модели - через модель представления - привязать к представлению - как?
|
|||
---|---|---|---|
#18+
Ой, последний вопрос отменяется. Я не разглядел, что в байндинге можно для кастомного типа параметра в разметке свойства этого параметра задавать. Тогда вроде должно получиться. Спасибо. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.01.2013, 16:02 |
|
Атрибуты свойств модели - через модель представления - привязать к представлению - как?
|
|||
---|---|---|---|
#18+
Так, я немножко изменил код и довёл его до ума. Надо было в конвертере не из value тип брать, т. к. понятно, что тип там будет - один из моделей представления, а завести четвёртое свойство класса MetadataParameters, которое будет содержать тип модели (не модели представления). Дальше всё то же самое по сути. Только вопрос, почему вы написали Код: c# 1. 2.
хотя в другом месте писали уже Код: c# 1.
Я сделал и там и там одинаковым образом. Вот что у меня получилось: Это в модели представления конвертер и вспомогательный класс к нему: Код: 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.
Это разметка: В файле ресурсов (XAML): Код: xml 1. 2. 3.
В файле представления (XAML): Код: xml 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.
... |
|||
:
Нравится:
Не нравится:
|
|||
27.01.2013, 21:07 |
|
Атрибуты свойств модели - через модель представления - привязать к представлению - как?
|
|||
---|---|---|---|
#18+
Ещё я не понял, зачем в строчке Код: c# 1.
вы написали new object[] { }. Я передал null и всё работало. Но теперь у меня другая проблема. Я, конечно, получаю то, что в модели в атрибуты завёл. Но в свойства этих атрибутов всё подставляется из ресрусрыных локализованных строк. Я догадываюсь, что можно как-то использовать параметр CultureInfo culture конвертера, но как? ... |
|||
:
Нравится:
Не нравится:
|
|||
27.01.2013, 21:11 |
|
Атрибуты свойств модели - через модель представления - привязать к представлению - как?
|
|||
---|---|---|---|
#18+
Что интересно, мне вообще не понадобился параметр value конвертера. И вся привязка к подели представления оказалась нужна только для того, чтобы передать конвертеру параметр, т. к. конвертеры без привязки не работают. Получается, что должно быть какое-то другое решение, без привязок, так как привязка по сути здесь выступает в роли костыля, который я использую только для вызова функции конвертера? ... |
|||
:
Нравится:
Не нравится:
|
|||
27.01.2013, 21:16 |
|
Атрибуты свойств модели - через модель представления - привязать к представлению - как?
|
|||
---|---|---|---|
#18+
user7320, Если нужно отобразить данные в ContentControl (например, в Label), то можно напрямую использовать этот самый MetadataParameters с переопределенным ToString: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.
Код: xml 1. 2. 3. 4. 5. 6. 7. 8. 9.
В случае с TextBlock такое не пройдет - содержимое свойства Text обязательно должно быть либо string, либо MarkupExtension - т.е. у нас только последний вариант. И в этом custom MarkupExtension вовсе не нужен binding - из ProvideValue можно сразу возвращать требуемое: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20.
Использование: Код: xml 1. 2. 3. 4. 5. 6. 7. 8. 9.
Нюанс: из-за одного достаточно старого бага при попытке использовать этот MarkupExtension в атрибутной нотации - вида Код: xml 1. 2. 3.
компилятор будет ругаться примерно так: Код: plaintext 1.
Причина - в наличии nested extensions (TypeExtension в данном случае). Если использовать property element syntax (как указано в первом примере разметки для TextBlock), то всё скомпилируется нормально. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.01.2013, 07:40 |
|
Атрибуты свойств модели - через модель представления - привязать к представлению - как?
|
|||
---|---|---|---|
#18+
Спасибо. А не могли бы вы подсказать ещё, как вытащить нужной культуры текст из свойств метаданных модели? Я делаю так и у меня не выходит: В модели Код: c# 1. 2. 3. 4. 5.
При этом в сборке модели файл с нужными строками есть - Strings.ru-RU.resx. Также есть дефолтный файл - Strings.resx, который повторяет содержимое ru-RU. В приложении, представляющем модель представления и представление: Код: c# 1. 2. 3. 4. 5. 6. 7.
В конвертере (я пока его использую): Код: c# 1. 2. 3. 4. 5. 6.
При этом без использования параметра culture конвертера (зачем он нужен? - я же и так в функцию GetValue передаю нужную мне культуру. Да и почему-то под дебагом видно, что культура в параметре конвертера всё равно стоит en-US. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.01.2013, 08:52 |
|
Атрибуты свойств модели - через модель представления - привязать к представлению - как?
|
|||
---|---|---|---|
#18+
Я ещё не уверен в правильности установки всех параметров этого варианта функции GetValue, но вроде, почитав в МСДНе, всё верно сделал. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.01.2013, 08:53 |
|
Атрибуты свойств модели - через модель представления - привязать к представлению - как?
|
|||
---|---|---|---|
#18+
Да, и при этом, если под дебагом посмотреть, на момент вызова GetValue значение Thread.CurrentThread.CurrentUICulture равно ru-RU, как я и установил в конструкторе приложения. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.01.2013, 08:55 |
|
Атрибуты свойств модели - через модель представления - привязать к представлению - как?
|
|||
---|---|---|---|
#18+
Да, забыл сказать, что проблема в том, что в интерфейсе показывает для Name-свойства атрибута значеие ExceedThresholdName вместо локализованной строки. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.01.2013, 08:56 |
|
Атрибуты свойств модели - через модель представления - привязать к представлению - как?
|
|||
---|---|---|---|
#18+
И ещё я забыл сказать, что у меня пока и модели, и ресурсы для модели, и модели представления в одной сборке находятся. И ещё дефолтная культура у меня в Виндовс стоит английская. Может, в этом дело, что у меня параметр culture конвертера английский? Но по идее, это не должно влиять на выбор строки из ресурсов в функции GetValue - ведь там я передал культуру какую надо. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.01.2013, 09:13 |
|
Атрибуты свойств модели - через модель представления - привязать к представлению - как?
|
|||
---|---|---|---|
#18+
О, нашёл ошибку! Вот это да! Почему-то DisplayAttribute не ищет значения в ресурсах, а просто выдаёт то, что ему в свойстве Name написали. Написал я там ключ из словаря ресурсов, а он не ищет значение по этому ключу, а просто название этого ключа и выводит. Я написал свой атрибут Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.
И использую его так Код: c# 1. 2.
И всё работает! Почему скотина DisplayAttribute так себя ведёт? Ведь написано же, что он специально сделан, чтобы по локализованные значения искать. И главное, у меня в проекте на ASP.NET MVC он работает. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.01.2013, 13:42 |
|
|
start [/forum/topic.php?fid=21&fpage=33&tid=1441512]: |
0ms |
get settings: |
8ms |
get forum list: |
12ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
69ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
55ms |
get tp. blocked users: |
1ms |
others: | 13ms |
total: | 176ms |
0 / 0 |