|
Как правильно в MVVM подсоединять методы к событиям?
|
|||
---|---|---|---|
#18+
В своё время, в первую очередь с помощью Roman Mejtes , в теме Правильное размещение функционала и привязки команд помогли разобраться с подключением команд и их всплытием в списочных элементах. Для иллюстрации привожу пример. В нём реализовано изменение выделения цветом текста при нажатии на кнопку в ListBoxItem. ViewModel с классом для списка. В них используются классы OnPropertyChangedClass - реализация INPC и RelayCommand - реализация ICommand. Здесь их не привожу, если понадобятся - они в приложенном архиве. Код: 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.
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. 38. 39. 40. 41.
Но как быть если нужно подсоединить метод к событию? Допустим, надо по двойному клику задублировать элемент. Использовать для этого триггеры взаимодействия (Interaction.Triggers) очень неудобно: их нельзя использовать в стилях, шаблонах, они не всплывают. На данный момент, в таких случаях, я использую CB окна. ViewModel с добавленным методом копирования Код: 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.
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. 38. 39. 40. 41. 42.
CB окна Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
Такая реализация мне категорически не нравится. Но как сделать по другому я не знаю. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.05.2019, 13:48 |
|
Как правильно в MVVM подсоединять методы к событиям?
|
|||
---|---|---|---|
#18+
Eld Hasp Код: xml 1. 2.
Извини, глубоко в твой код не вчитывался, но что мешает перехватывать всплывающее событие и направлять его на RelayCommand точно так же, как перехватывается всплывающая команда. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.05.2019, 13:53 |
|
Как правильно в MVVM подсоединять методы к событиям?
|
|||
---|---|---|---|
#18+
Shocker.ProEld Hasp..., но что мешает перехватывать всплывающее событие и направлять его на RelayCommand точно так же, как перехватывается всплывающая команда. Но для этого надо подсоединить к событию не обработчик, а команду (RoutedCommand или RoutedUICommand) добавить передачу параметра для этой команды. Как сделать это с помощью триггеров взаимодействия я знаю. Но команды подсоединённые таким образом не всплывают и их нельзя использовать в стилях и шаблонах. Ну, или я их не правильно подключаю. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.05.2019, 14:07 |
|
Как правильно в MVVM подсоединять методы к событиям?
|
|||
---|---|---|---|
#18+
Не надо к нему команду присоединять. Я же привел кусок твоего кода. Будет примерно так: Код: xml 1. 2.
... |
|||
:
Нравится:
Не нравится:
|
|||
19.05.2019, 14:13 |
|
Как правильно в MVVM подсоединять методы к событиям?
|
|||
---|---|---|---|
#18+
Shocker.ProНе надо к нему команду присоединять. Я же привел кусок твоего кода. Будет примерно так: Код: xml 1. 2.
То есть изменить реализацию ContextHolder? Даже если изменить реализацию ContextHolder для отлова событий, то всё равно не выйдет. Так как событие не имеет параметра как команда. И для обработки события View в ViewModel придётся работать с UI элементами View и нужны знания о их компоновке в View. А это, на мой взгляд, неправильно. Это тоже самое, как вместо команды передавать в ViewModel событие Click. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.05.2019, 14:49 |
|
Как правильно в MVVM подсоединять методы к событиям?
|
|||
---|---|---|---|
#18+
Eld HaspТо есть изменить реализацию ContextHolder?не изменить, а дополнить Eld HaspТак как событие не имеет параметра как команда.почему не имеет? RoutedEventArgs - вот параметры. Eld HaspИ для обработки события View в ViewModel придётся работать с UI элементами View и нужны знания о их компоновке в View.нет, ты же при привязке команды к кнопке не рассказываешь VM он компоновке. Фактически, ты можешь с тем же успехом перехватить Button.Click вместо Command И что самое интересное, если ты в качестве RelayCommand вместо Binding укажешь Static на какую-то команду, то она пойдет себе дальше по дереву. То есть с помощью уже имеющегося у тебя local:CommandBinding ты можешь конвертировать одну команду в другую в какой-то точке всплытия и она поплывет дальше. А с помощью потенциального local:RoutedEventBinding ты точно так же можешь конвертировать событие в команду, если это понадобится ... |
|||
:
Нравится:
Не нравится:
|
|||
19.05.2019, 15:14 |
|
Как правильно в MVVM подсоединять методы к событиям?
|
|||
---|---|---|---|
#18+
Shocker.Proпочему не имеет? RoutedEventArgs - вот параметры.если же необходимо совместить - я паковал в такой класс Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9.
... |
|||
:
Нравится:
Не нравится:
|
|||
19.05.2019, 15:15 |
|
Как правильно в MVVM подсоединять методы к событиям?
|
|||
---|---|---|---|
#18+
Shocker.ProEld HaspТак как событие не имеет параметра как команда.почему не имеет? RoutedEventArgs - вот параметры.я неправильно прочитал вопрос, ну да ладно ... |
|||
:
Нравится:
Не нравится:
|
|||
19.05.2019, 15:24 |
|
Как правильно в MVVM подсоединять методы к событиям?
|
|||
---|---|---|---|
#18+
Shocker.Proне изменить, а дополнитьДа, это я понял. Просто, может, неправильно выразился. Shocker.Proпочему не имеет? RoutedEventArgs - вот параметры. ......... нет, ты же при привязке команды к кнопке не рассказываешь VM он компоновке. Фактически, ты можешь с тем же успехом перехватить Button.Click вместо Command За параметры события я знаю. Но параметры команды это несколько иное. В лучшем случае мне придётся приводить источник события к какому-то UI элементы и из его свойства вытаскивать значение для привязки параметра. Как у меня сейчас сделано в этом коде CB окна Код: c# 1. 2. 3. 4. 5.
Я привожу источник команды к ButtonBase и извлекаю параметр из button.CommandParameter. Делая это в VM, получается надо знать какого типа источник события и в каком свойстве источника события содержится параметр. Обработка " RoutedEventArgs e " тоже немного помогает в этом. Shocker.ProА с помощью потенциального local:RoutedEventBinding ты точно так же можешь конвертировать событие в команду, если это понадобитсяНадо подумать над этим. Не приходит в голову как можно решить с параметром... ... |
|||
:
Нравится:
Не нравится:
|
|||
19.05.2019, 15:31 |
|
Как правильно в MVVM подсоединять методы к событиям?
|
|||
---|---|---|---|
#18+
Я никак не пойму твою проблему с параметром. Что тебе мешает Код: xml 1. 2. 3.
... |
|||
:
Нравится:
Не нравится:
|
|||
19.05.2019, 15:38 |
|
Как правильно в MVVM подсоединять методы к событиям?
|
|||
---|---|---|---|
#18+
Shocker.ProЯ никак не пойму твою проблему с параметром. Что тебе мешает Код: xml 1. 2. 3.
Так можно подсоединить параметр в точке отлова всплытия. А нужно в месте возникновения события. Как здесь для команды Код: xml 1. 2. 3. 4. 5. 6.
... |
|||
:
Нравится:
Не нравится:
|
|||
19.05.2019, 15:43 |
|
Как правильно в MVVM подсоединять методы к событиям?
|
|||
---|---|---|---|
#18+
Eld HaspТак можно подсоединить параметр в точке отлова всплытия.Для этого существует достаточно стандартный паттерн - присоединяемое свойство, которое ты можешь присоединить непосредственно к Button. Но я не вижу проблемы. Как с командой, так и с событием, используемый ContextHolder существует в том же DataContext-е, что и кнопка, так что CommandParameter="{Binding}" точно так же сработает как для события, так и для команды ... |
|||
:
Нравится:
Не нравится:
|
|||
19.05.2019, 20:16 |
|
Как правильно в MVVM подсоединять методы к событиям?
|
|||
---|---|---|---|
#18+
Shocker.ProEld HaspТак можно подсоединить параметр в точке отлова всплытия.Для этого существует достаточно стандартный паттерн - присоединяемое свойство, которое ты можешь присоединить непосредственно к Button. Но я не вижу проблемы. Как с командой, так и с событием, используемый ContextHolder существует в том же DataContext-е, что и кнопка, так что CommandParameter="{Binding}" точно так же сработает как для события, так и для командыButton - приведён для иллюстрации вопроса - как это сделано для команды. А так в этом месте может стоять любой элемент. Допустим, TextBlock и у него нет свойства CommandParameter. А если надо обрабатывать два разных события и у каждого своя привязка параметра, то... вооще лес дремучий. Просто сделать - я могу. Но хочется сделать красиво: и чтобы с MVVM не противоречить, и CB окна не использовать, и чтобы в стилях, шаблонах можно было использовать, и отделить само событие от команды выполняющейся по событию (как Click и Command). С присоединяемыми свойствами - не пробовал. Надо повозиться. Пока не совсем хорошо представляю как их делать кастомно. Почитаю. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.05.2019, 21:23 |
|
Как правильно в MVVM подсоединять методы к событиям?
|
|||
---|---|---|---|
#18+
Eld Hasp, В событие на double click добавьте код возбуждающий маршрутизируемую команду, она в свою очередь, через маршрутизиуремые события всплывет наверх и будет обработано в ContentHolder'е, добавить команду кнопке можно через AP или Behavior, или в CodeBehind файле, как вам угодно. У делегата маршрутизируемого события команд есть параметр, который передается, если параметр не нужен, просто не используйте его. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.05.2019, 23:54 |
|
Как правильно в MVVM подсоединять методы к событиям?
|
|||
---|---|---|---|
#18+
Eld HaspС присоединяемыми свойствами - не пробовал. Надо повозиться. Пока не совсем хорошо представляю как их делать кастомно. Почитаю. Аккуратнее - здесь есть неприятный подводный камень с утечкой памяти. Сама по себе реализация там проста, как первый русский трактор: при изменении присоединенного свойства (тип свойства - ICommand) - через биндинг, или напрямую, роли не играет - в PropertyChangedCallback к DependencyObject присобачивается банальный обработчик нужного события, вызывающий эту нашу ICommand. Если объекты, которые подписываются на события, являются, например, частями DataTemplate, и/или соответствующие им элементы VM могут массово создаваться/уничтожаться, то если забыть корректно отписать объект от обработчика, будут утечки памяти. А если подписываемый DependencyObject находится выше по иерархии наследования, чем FrameworkElement, то там даже не будет события OnUnload, чтобы автоматически отписываться по нему. А вообще всё вышеописанное, и вроде как с аккуратно обработанными граблями с утечками памяти есть здесь: https://www.nuget.org/packages/AttachedCommandBehavior/ ... |
|||
:
Нравится:
Не нравится:
|
|||
27.05.2019, 08:20 |
|
Как правильно в MVVM подсоединять методы к событиям?
|
|||
---|---|---|---|
#18+
Сон Веры ПавловныАккуратнее - здесь есть неприятный подводный камень с утечкой памяти.... А вообще всё вышеописанное, и вроде как с аккуратно обработанными граблями с утечками памяти есть здесь: https://www.nuget.org/packages/AttachedCommandBehavior/ Спасибо! ... |
|||
:
Нравится:
Не нравится:
|
|||
27.05.2019, 10:44 |
|
|
start [/forum/topic.php?fid=21&fpage=3&tid=1440326]: |
0ms |
get settings: |
9ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
45ms |
get topic data: |
13ms |
get forum data: |
3ms |
get page messages: |
58ms |
get tp. blocked users: |
2ms |
others: | 257ms |
total: | 409ms |
0 / 0 |