powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Зависимости в MVVM в WPF
38 сообщений из 38, показаны все 2 страниц
Зависимости в MVVM в WPF
    #39073991
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Итак, мы имеем для каждого представления:
- собственно представление (XAML)
- CodeBehind-модуль для XAML
- модель представления (ViewModel)
- уровень бизнес-логики (модель или контроллер, который управляет организацией представлений и т.п.)

Как правильно простроить зависимости, чтобы не получить в будущем спагетти?

Изначально одна зависимость уже есть CodeBehind зависит от XAML. Кто должен зависеть от VM, от кого она должна зависеть и где вообще ее место в жизненном цикле? Экземпляр VM должен создавать XAML или CodeBehind или же она должна формироваться в бизнес-логике и передаваться как параметр при создании экземпляра представления? Как с представлением взаимодействует бизнес-логика - через VM или через CodeBehind (опять же, учитывая то, что не все события, возникающие в CodeBehind, можно через ICommand ловить в VM)
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39074037
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
когда надо быстро, я в
app.xaml
добавляю ресурс:
<vm:MainModel x:Key=MainMOdel/>
и в форме DataContext={StaticResource MainModel}

если надо сложнее логику, то в App.xaml можно указать процедуру загрузки и в ней создать\загрузить VM, создать V и связать.
CodeBehind я лично не отделаю от View, но смысл в том, что CB не должен зависеть от VM, то есть взаимодействие только с объектами визуального дерева и не более.

Возникает еще 1 момент, это окна, как открыть новое окно из VM? =)
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39074048
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman Mejtesсоздать\загрузить VM, создать V и связать.то есть уровень бизнес-логики зависит и от V и от VM? А связываешь ты как. Бизнес модель привязывает MyView.DataContext=MyVM?

А с чем взаимодействует бизнес-логика? Откуда забирает и куда докидывает данные, откуда получает события?

Как поступать, если нужно, чтобы события взаимодействовали с ViewModel, если сам CodeBehind не зависит от VM? Транслировать через View, налепливая какие-то дополнительные ICommand?
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39074060
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.ProRoman Mejtesсоздать\загрузить VM, создать V и связать.то есть уровень бизнес-логики зависит и от V и от VM? А связываешь ты как. Бизнес модель привязывает MyView.DataContext=MyVM?

А с чем взаимодействует бизнес-логика? Откуда забирает и куда докидывает данные, откуда получает события?

Как поступать, если нужно, чтобы события взаимодействовали с ViewModel, если сам CodeBehind не зависит от VM? Транслировать через View, налепливая какие-то дополнительные ICommand?
Передавать события в MVVM невозможно, но совершенно спокойно можно передать делегат или предикат как свойство, через связывание.

Я использую RoutedCommand и ICommand в паре. Для этого я сделал класс слушатель, он следит за автоматизируемым событием CommandExecute и CommandCanExecute и когда оно "всплывает" (так как оно бабл), вызывается связанная с этим маршрутизируемой командой, команда из модели представления (ICommand) .
Всё взаимодействие из направлении из View в ViewModel идет через команды, особенно RoutedCommand вывозят в ContentPresenter'ах, списках и прочих контейрерах + кнопки + элементы меню + Application.commands.

Обычно весь View я делаю в DataTemplate'ах, а ContentControl'ы (такие как формы и userControl'ы) использую очень редко, проще сделать шаблон и отобразить его в Presenter'е для любой модели. По этому CodeBehind у меня весь находится не в прикрепленных к XAMLу файлах с кодом, а отдельно в хелперах, либо я создаю нужный мне контрол с нужным поведением на базе существующих или скомпонованный из существующих примитивов. То есть, в XAML файлах кода в 99% случаев нет вообще, если он нужен он привязывается в дереве там, где необходим через Interactive или AttachedProperty.
Грубо говоря, если мне нужно добавить логику Drag&Drop для панели, я создаю класс DragDropHelper, в нем прикрепляемое свойсто
IsDragDropEnabled и когда его значение меняется на тру, для контрола к котому применяется значение прикрепляются все нужные мне обработчики событий. Получается, что вся логика отвечающая за Drag & Drop у меня в отдельном классе.
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39074066
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman MejtesВсё взаимодействие из направлении из View в ViewModel идет через командыНо ведь не все события спроецированы на команды, тут приходится поучаствовать CodeBehind-у. Как ты отправляешь эти события обратно в представление, чтобы они приобрели интерфейс ICommand?
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39074231
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.ProИзначально одна зависимость уже есть CodeBehind зависит от XAML.Только если XAML содержит именованные элементы.
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39074493
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КShocker.ProИзначально одна зависимость уже есть CodeBehind зависит от XAML.Только если XAML содержит именованные элементы.
а что это дает для VM? =) VM ни чего не знает об объектах View их именнованности и в VM не должно быть не 1 ссылки на объекты View модели
2_Shocker.Pro : я тебе накидаю пример проекта и кину сюда чуток по позже, сегодня или завтра. Сегодня я что то приболел слегка, там будет как раз пример, как перехватить событие во View и вызвать соответствующую команду в ViewModel через команды, в CodeBehind или прямо из XAML.
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39074553
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
да, я ступил, для отлова событий ведь необязательно именовать объекты, так что таки-да, нет зависимости. Но, с другой стороны CB, конечно, самостоятельным объектом не является.

Roman Mejtes, спасибо, это будет полезно.

В любом случае, вопрос был и более общий о проектах с длинной перспективой развития - как правильно организовать зависимости|? чтобы в будущем не поиметь проблем. То есть, как я понял - это нормальная практика - делать зависимость бизнес-логики от VM.
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39074714
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman MejtesАлексей Кпропущено...
Только если XAML содержит именованные элементы.
а что это дает для VM? =) VM ни чего не знает об объектах View их именнованности и в VM не должно быть не 1 ссылки на объекты View моделиНу если XAML не содержит именованных элементов, то code-behind не может иметь ссылок на них - в этом случае code-behind классическая ViewModel.

зы: Экзотические случаи не рассматриваем.
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39074725
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.Proда, я ступил, для отлова событий ведь необязательно именовать объекты, так что таки-да, нет зависимости. Но, с другой стороны CB, конечно, самостоятельным объектом не является .Это можно считать не только недостатком, но и преимуществом, в зависимости от ситуации.
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39074747
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.ProВ любом случае, вопрос был и более общий о проектах с длинной перспективой развития - как правильно организовать зависимости|? чтобы в будущем не поиметь проблем.Всё как всегда - сразу продумать способ разделения на функциональные модули (например, множество банальных UserControl). Модули делать простыми, усложнять их по мере необходимости: например, если всё умещается в code-behind, то зачем выдумывать что-то ещё.
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39074853
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей Кв этом случае code-behind классическая ViewModel.Ну тогда вопрос - стремиться ли выделить VM как отдельный класс, или наоборот - стремиться уминать все в CB?
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39074854
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей Кнапример, множество банальных UserControlну вопрос-то при этом не отпадает - UC сам имеет свою VM и меняется только масштаб вопроса )
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39074991
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КRoman Mejtesпропущено...

а что это дает для VM? =) VM ни чего не знает об объектах View их именнованности и в VM не должно быть не 1 ссылки на объекты View моделиНу если XAML не содержит именованных элементов, то code-behind не может иметь ссылок на них - в этом случае code-behind классическая ViewModel.

зы: Экзотические случаи не рассматриваем.
нам не надо знать имя элемента, чтоб обработать его события через Interactive.Behavior или AttachedProperty, нам не надо знать имена чтоб получить RoutedEvent или RoutedCommand.
Единственное, что в XAML надо использовать имена, это связывание между элементами, анимация, триггеры, части шаблона (PartTemplate атрибут)
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39075023
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.ProАлексей Кв этом случае code-behind классическая ViewModel.Ну тогда вопрос - стремиться ли выделить VM как отдельный класс, или наоборот - стремиться уминать все в CB?Ну я для себя решил, что по дефолту всё делается в CB, выносится в отдельный класс по необходимости: например, если вдруг потребуется наследование VM - CB этого к сожалению не умеет.
Shocker.ProАлексей Кнапример, множество банальных UserControlну вопрос-то при этом не отпадает - UC сам имеет свою VM и меняется только масштаб вопроса )Внутри каждого UC вопрос может решаться по разному, в зависимости от масштабов и особенностей каждого отдельного подвопроса. :-)

С другой стороны, здесь многое решают личные предпочтения. У меня в последнее время приоритеты в сторону простоты и минимального объёма кода. Если на каждый чих делать присоединяемые свойства, как тому учат современные практики - это никак не попадает под мои критерии абсолютной правильности. :-)
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39075025
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman MejtesАлексей Кпропущено...
Ну если XAML не содержит именованных элементов, то code-behind не может иметь ссылок на них - в этом случае code-behind классическая ViewModel.

зы: Экзотические случаи не рассматриваем.
нам не надо знать имя элемента, чтоб обработать его события через Interactive.Behavior или AttachedProperty, нам не надо знать имена чтоб получить RoutedEvent или RoutedCommand.
Единственное, что в XAML надо использовать имена, это связывание между элементами, анимация, триггеры, части шаблона (PartTemplate атрибут)Я в курсе. :-)
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39075563
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КShocker.Proпропущено...
Ну тогда вопрос - стремиться ли выделить VM как отдельный класс, или наоборот - стремиться уминать все в CB?Ну я для себя решил, что по дефолту всё делается в CB, выносится в отдельный класс по необходимости: например, если вдруг потребуется наследование VM - CB этого к сожалению не умеет.
Shocker.Proпропущено...
ну вопрос-то при этом не отпадает - UC сам имеет свою VM и меняется только масштаб вопроса )Внутри каждого UC вопрос может решаться по разному, в зависимости от масштабов и особенностей каждого отдельного подвопроса. :-)

С другой стороны, здесь многое решают личные предпочтения. У меня в последнее время приоритеты в сторону простоты и минимального объёма кода. Если на каждый чих делать присоединяемые свойства, как тому учат современные практики - это никак не попадает под мои критерии абсолютной правильности. :-)
я общался с другим гуру XAML, так сказать со своими учителем, многие его подходы к разным способом реализации функционала и бизнес логики отличаются от моих, как он говорил, если твой подход работает, он удобен для тебя, пользуйся им :) и радуйся жизни.
Можно и MVC шаблон использовать в XAML, этого ни кто не запрещает.
Лично я предпочитаю, когда все XAML файлы являются просто ресурсами которые я потом использую, следовательно CodeBehind я выношу в отдельные классы которые не размазаны по форму или xaml файлу с кодом или разбиты на Partial, плюс когда нужное поведение в отдельном классе, я могу его легко повторно использовать в любой другой части и даже в другой ситуации, если он универсален.
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39075615
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman MejtesЛично я предпочитаю, когда все XAML файлы являются просто ресурсами которые я потом использую, следовательно CodeBehind я выношу в отдельные классы которые не размазаны по форму или xaml файлу с кодом или разбиты на Partial,Цель не понятна, усложнения очевидны.
Roman Mejtesплюс когда нужное поведение в отдельном классе, я могу его легко повторно использовать в любой другой части и даже в другой ситуации, если он универсален.UC тоже можно повторно использовать в "любой другой части и даже в другой ситуации, если он универсален".
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39151806
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman MejtesПередавать события в MVVM невозможно, но совершенно спокойно можно передать делегат или предикат как свойство, через связывание.

Я использую RoutedCommand и ICommand в паре. Для этого я сделал класс слушатель, он следит за автоматизируемым событием CommandExecute и CommandCanExecute и когда оно "всплывает" (так как оно бабл), вызывается связанная с этим маршрутизируемой командой, команда из модели представления (ICommand) .
Всё взаимодействие из направлении из View в ViewModel идет через команды, особенно RoutedCommand вывозят в ContentPresenter'ах, списках и прочих контейрерах + кнопки + элементы меню + Application.commands.

Roman Mejtes
, хочу вернуться к этому вопросу. Я сейчас сам столкнулся с ситуацией, когда хочу получить одновременно поведение ICommand (то есть присоединить команду через {Binding} во ViewModel), но в то же время хочу, чтобы команда всплывала как RoutedCommand.

При этом получается, что в CommandBinding я должен указать Executed="хендлер", который находится в Code Behind. Я так не понял, как ты смог прикрутить ICommand к RoutedCommand?

Если ты разместил этот "слушатель" в Code Behind - это значит, что ты наследуешь все окна от какого-то своего базового класса, а не от Window? И как ты определяешь в нем, что именно является VM (чтобы передать событие)?

В общем, буду признателен за примерчик
Roman Mejtes2_Shocker.Pro : я тебе накидаю пример проекта и кину сюда чуток по позже, сегодня или завтра.
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39151866
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman Mejtesв XAML файлах кода в 99% случаев нет вообще, если он нужен он привязывается в дереве там, где необходим через Interactive или AttachedProperty.
Грубо говоря, если мне нужно добавить логику Drag&Drop для панели, я создаю класс DragDropHelper, в нем прикрепляемое свойсто
IsDragDropEnabled и когда его значение меняется на тру, для контрола к котому применяется значение прикрепляются все нужные мне обработчики событий. Получается, что вся логика отвечающая за Drag & Drop у меня в отдельном классе.100 раз перечитал все это, на 101-й начало немного доходить... ))

Под Interactive ты имеешь ввиду поведения? То есть наследники Behavior<>? правильно я понял?
В таком случае, присоединение логики через присоединяемое свойство - это почти то же самое, только лишнюю библиотеку тянуть не надо )

Но вопрос в другом - таким образом ты придаешь поведение некоторому ОДНОМУ элементу, это удобно для стандартных и относительно универсальных поведений. Но я не понял, как ты поступаешь, когда нужно наполнить форму логикой. Скажем, есть пяток-десяток кнопок, которые надо оживить и которые должны в итоге работать в едином контексте (логично бы в контексте VM). Как ты поступаешь?
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39152448
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
тыц

пример в проекте, в папке View XAML словари с представлением, в MainView пример CommandListener,
в PersonView для кнопки Delete задана маршрутизируемая команда,
в проекте нет Window вообще, запускает приложение через Application.Statup=<handler>,
ActionCommand - это обычный RelayCommand, просто у меня в проектах он малость навороченный, это тут не нужно

Код: xml
1.
2.
3.
4.
5.
6.
7.
            
            <commands:CommandListener.CommandsCollection>
                <commands:CommandsCollection>
                    <commands:CommandBind RoutedCommand="{x:Static commands:RoutedCommands.Remove}"
                                          Command="{Binding RemoveCommand}"/>
                </commands:CommandsCollection>
            </commands:CommandListener.CommandsCollection>



<commands:CommandListener.CommandsCollection> - это обычный AttachedProperty, цеплять можно к любому
<commands:CommandsCollection> - Это FreezableCollection, её необходимо создавать самому, так как AttachedProperty нельзя инициализировать сразу,
commands:CommandBind - это freezble объект, у него есть 3 свойства:
RoutedCommand - указывается маршрутизируемая команда, которая будет прослушиваться
Command - команда которая будет вызывать в контексте ViewModel
IsHandled - это свойство по умолчанию равно True, если указать False, то после того как команда обработается, она продолжит всплывать по дереву и если встретит еще 1 CommandListener то будет обработана еще раз. То есть 1 RoutedCommand можно вызвать 2 разные команды в моделях на разных уровнях, выполняться они будут конечно же в том порядке, в каком расположены в дереве снизу вверх (от ветвей к корню).
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39152450
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ах да, как ты и просил, в проекте нет не 1 XAML файла с CodeBehind )
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39152455
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.Pro,

авторНо вопрос в другом - таким образом ты придаешь поведение некоторому ОДНОМУ элементу, это удобно для стандартных и относительно универсальных поведений. Но я не понял, как ты поступаешь, когда нужно наполнить форму логикой. Скажем, есть пяток-десяток кнопок, которые надо оживить и которые должны в итоге работать в едином контексте (логично бы в контексте VM). Как ты поступаешь?
не понял вопроса, о чем конкретно идет речь?
вся логика модели, должна быть в моделе,а View её только отражать (логику). Если кнопка не должна работать, значит метод OnCanBlaBlaBla должен реализовывать это в модели для данного ICommand.
Что понимается, под словом оживить?
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39152462
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman Mejtes,

Ага, спасибо огромное, ща буду изучать.
Пока ждал ответа, сам почти сделал хелпер, который устанавливает свойство связанной модели при клике на кнопку, судя по всему, подход понял правильно.
Код: xml
1.
2.
3.
4.
5.
      <Button Content="Редактировать">
        <local:OnClicker.PropChanger>
          <local:PropertyChanger Binding="{Binding EditingMode}" Value="true" />
        </local:OnClicker.PropChanger>
      </Button>
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39152474
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman MejtesShocker.Pro,

авторНо вопрос в другом - таким образом ты придаешь поведение некоторому ОДНОМУ элементу, это удобно для стандартных и относительно универсальных поведений. Но я не понял, как ты поступаешь, когда нужно наполнить форму логикой. Скажем, есть пяток-десяток кнопок, которые надо оживить и которые должны в итоге работать в едином контексте (логично бы в контексте VM). Как ты поступаешь?
не понял вопроса, о чем конкретно идет речь?
вся логика модели, должна быть в моделе,а View её только отражать (логику). Если кнопка не должна работать, значит метод OnCanBlaBlaBla должен реализовывать это в модели для данного ICommand.
Что понимается, под словом оживить?Ну, то есть в VM ты создаешь n-ное количество реализаций ICommand и привязываешь их через к кнопкам через Command="{Binding blabla}" - правильно я понял?

А если у конкретного источника нет свойства Command для нужного события, ты вешаешь на него свой листенер, как показано выше, и все равно заставляешь его выполнять ICommand в VM? Правильно я понял?
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39152498
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
если объект наследует ICommandSource (BaseButton и её наследники или др.), то у него есть свойство Command, можно сразу на него биндить команду, если это позволяет реализация модели, но к примеру если это просто сущность (элемент ListBox) то у него может быть не быть реализован в модели обработчик команды ICommand (ты же не можешь удалить Person из самого Person), тогда я к Command (например кнопки) задают маршрутизируемую команду и обрабатываю её на том уровне, где этот обработчик реализован. Как в примере, у Person нет ни каких команд, команда есть в MainModel, и именно эта команда вызывается при нажатии на урну и удаляет Person из коллекции.
То есть для любой команды пользователя в UI будет реализована соответствующая команда в модели.
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39153051
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman Mejtes,

C твоим принципом отделения разметки формы в ресурсы разобрался )
Там есть попутные вопросы, но об этом позже.

Что касается твоего listener-а - я бы кратко охарактеризовал так: ты создал замену для штатного CommandBindings/CommandBinding, которая, в отличие от штатного, может выполнять код (ICommand) не в CodeBehind, а в VM посредством привязки. Правильно я понял?

Я же пытался выяснить несколько другой вопрос - как в VM без использования CodeBehind выполнить код по событию контрола, для которого нет команды. Ну, скажем, KeyDown. Попытку решения я приложил чуть выше, но эта обработка решается просто через RelayCommand, всплытия команды по дереву нет. А как это решаешь ты?
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39153433
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.Pro,

смысл в том, что вся интерактивность должна оставаться в рамках View, то есть, если нам нужно сделать, к примеру, обработку на кнопки KeyDown, то мы просто добавляем AttachedProperty или через Interactive соответствующее поведение.
В результате выполнения этого поведения должна быть вызвана та или иная команда (либо маршрутизируемая, либо обычная, которую мы получим из свойства которое так же приатачим к этому элементу управления).

Передавать события в VM не нужно, в этом нет необходимости, все события View должны обрабатывать на том же уровне.
К примеру, нам надо сделать DragAndDrop, соответственно в представлении (во View) я создаю класс с прикрепляемым свойством
IsCanDrag и привязываю это свойство со значением True к тем объектам, которые я хочу перетаскивать.
В методе OnChanged для данного AttachedProperty, если значение равно True я подписываюсь на 3 события MouseDown, MouseMove, MouseUp, где определяю логику захвата данного элемента управления для перетаскивания и вызывают DragDrop.DoDragDrop().
Для объекта в который идет перетаскивание создает свойство IsCanDrop, где так же добавляются обработчики на события Drop и др.
И свойство DropCommand которое будет связано с командой которая будет вызываться по завершению перетаскивания.
То есть вся логика, отвечающая за перетаскивание объекта лежит на View, а не ViewModel, а все её ньюансы настраиваются через свойства и связывание. В результате я могу применять это поведение практически к любым элементам управления.

Так же, не нужно пренебрегать наследованием. Очень часто я делаю свои контролы с нуля или наследую существующие, в которых определяю всю логику их работы, но как и в первом случаи сам по себе контрол ни чего не знает о ViewModel, у него есть набор DependencyProperty через которые и настраивается его поведение и внешний вид.
То есть сам контрол делает с расчетом на том, что он ни чего не знает о классах модели представления. Сам контрол взаимодействует только со своими свойствами и инициирует выполнение тех или иных команд.
Маршрутизируемые команды можно просто выполнить в код как "Команда.Execute(параметры)" и она тут же всплывает из того контрола в котором её вызывали. Контрол должен быть инкапсулированым и полностью самодостаточным.

Если мне нужна сложная логика размещения\компоновки элементов управления, я создаю свою панель, прибегаю я к этому не часто, так как существующие панели (при их комбинировании) дают довольно широкий спектр возможностей для компоновки

Если прямого взаимодействия между View и ViewModel невозможно избежать, то можно использовать Interface'ы, модель представления реализует заданный интерфейс, эта модель биндится к заданному свойству, элемент управления во View проверяет, полученный объект на и дергает за нужные методы\свойства\события этого интерфейса.
Такой подход реализован в INotifyPropertyChanged, ICollectionView, INotifyCollectionChanged, ICommand и всех это устраивает. Ведь такой подход остается униварсальным.
Вы знаете, что есть контрол для которого в 1 из свойств передается соответствующий интерфейс, вы его реализуете прикрепляете и всё в шоколаде.
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39153462
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну, собственно, об этом я и спрашивал - то есть обработка событий идет через поведения или AttachedProperty. Ну теоретизировать и высасывать ситуацию из пальца щас не буду, а если столкнусь, то буду перечитывать твой пост, пока не пойму, как можно обойтись поведением.

Кстати, а как ты выбираешь, когда применить поведение, а когда AttachedProperty? Ведь функционально это почти одно и то же, за исключением нюансов разметки.

Roman Mejtesя делаю свои контролы с нуля или наследую существующие, в которых определяю всю логику их работы, но как и в первом случаи сам по себе контрол ни чего не знает о ViewModel, у него есть набор DependencyProperty через которые и настраивается его поведение и внешний вид.то есть в данном случае ты как раз и используешь CodeBehind? И своей VM для внутренних у контрола нет, он взаимодействует только с тем, что ему назначит использующий его родитель.
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39153592
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.ProИ своей VM для внутренних у контрола нетдля внутренних нужд*
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39157244
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
когда мне надо быстро, без заморочек с подключением сборки Interactive я использую AttachedProperty, а так как я ленивая скотина, я использую его в большинстве случаев, так как это просто, удобно и главное понятно, я же могу быстро посмотреть что задает это свойство, видно, что оно не "родное". + я могу определить, что данное свойство влияет на пересчет размеров, компоновки и рендеринга.

очень часто приходится сталкиваться с низкой производительностью чисто декларативного подхода, тогда приходится создавать свой собственный контрол, который будет сделан на основе Visual объектов, но тут нужно подходить с умом. Знать когда использовать Visual, когда UIControl'ы, каждый UIControl наследуется от Visual, но поверх там наколбашено очень много всего.
Производительность Visual на много больше, но возможностей у них на много меньше. Мы по сути, можем определить только как выглядит объект, и где он находится, всю логику взаимодействия нужно делать в рамках класса (например) Control.
Visual объект можно поместить в UIElement, но UIElement нельзя поместить в Visual (не считая VisualBrush и BitmapCacheBrush, да и за помещение это назвать сложно). Но можно создать визуальное дерево самих Visual объектов, если в этом есть необходимость.
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39239617
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Роман, по твоему опыту - есть ли принципиально ситуации, где ViewModel требуется наследовать от DependencyObject (чтобы создавать свойства зависимости) или во всех случаях достаточно INotifyPropertyChanged?
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39239639
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.ProРоман, по твоему опыту - есть ли принципиально ситуации, где ViewModel требуется наследовать от DependencyObject (чтобы создавать свойства зависимости) или во всех случаях достаточно INotifyPropertyChanged?
такого не было :) и не будет.
возможно просто этому свойству место во View, в не во ViewModel.

Если свойство контрола (во View), не DP, а обычное, то возникает проблема связывания.
ак как невозможно связать вместе два обычных свойства, тогда, обычно, используют Proxy класс который будет осуществлять это связывание.
Но тут возникает еще несколько проблем:
а) в свойстве контрола, при изменении может не вызывается INotifyPropertyChanged.OnPropertyChanged, следовательно через Proxy всё равно нельзя будет обновить значение во ViewModel, если оно изменится во View
б) такая канитель сильно запутывает код

по этому такими вещами редко страдаю, я даже отказался от SelectedItems свойства (для примеру) у ListBox. Вместо этого, у меня для списков есть обёрточный класс, он сам оповещает меня о том, что выделение изменилось, как только у одного из элементов списка свойства IsSelected изменится, при чем, если оно изменится не у одного, а у нескольких элементов (когда выделение Single, с одного элементы IsSelected становится False, а у другого True), то я всё равно получу один вызов события, а в событие сразу передается список выделенных элементов, через Dispatcher
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39239913
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ясно, спасибо.

Я вроде к этому сам пришёл, но решил свериться с гуру ))
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Зависимости в MVVM в WPF
    #39616427
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Роман, а вот такой вопросик возник по этому коду.
Ты подписываешься на команду
Код: c#
1.
2.
            CommandManager.AddExecutedHandler(uielement, ExecuteHandler);
            CommandManager.AddCanExecuteHandler(uielement, CanExecuteHandler);

Фактически ты отдаешь и элемент и свой хендлер CommandManager-у, который по идее хранит ссылки на них.

А нет ли тут утечки, когда uielement должен быть уничтожен вместе с деревом, но на них еще висят ссылки в CommandManager. Или ты с этим как-то борешься?
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39618863
refreg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.Pro,

Код: 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.
    class Program
    {
        static void Main(string[] args)
        {
            var strongSubscriber = new Subscriber();
            var strongSubscriberReference = new WeakReference(strongSubscriber);
            CommandManager.RequerySuggested += strongSubscriber.SomeMethod;

            var weakSubscriber = new Subscriber();
            var weakSubscriberReference = new WeakReference(weakSubscriber);
            CommandManager.RequerySuggested += strongSubscriber.SomeMethod;
            weakSubscriber = null;

            GC.Collect();

            Console.WriteLine(strongSubscriberReference.IsAlive); // True
            Console.WriteLine(weakSubscriberReference.IsAlive); // False
        }

    }

    class Subscriber
    {
        public void SomeMethod(object sender, EventArgs e)
        {
            Console.WriteLine("SomeMethod is runned");
        }
    }
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39618865
refreg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.Pro,

Код: 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.
    class Program
    {
        static void Main(string[] args)
        {
            var strongSubscriber = new Subscriber();
            var strongSubscriberReference = new WeakReference(strongSubscriber);
            CommandManager.RequerySuggested += strongSubscriber.SomeMethod;

            var weakSubscriber = new Subscriber();
            var weakSubscriberReference = new WeakReference(weakSubscriber);
            CommandManager.RequerySuggested += weakSubscriber.SomeMethod;
            weakSubscriber = null;

            GC.Collect();

            Console.WriteLine(strongSubscriberReference.IsAlive); // True
            Console.WriteLine(weakSubscriberReference.IsAlive); // False
        }

    }

    class Subscriber
    {
        public void SomeMethod(object sender, EventArgs e)
        {
            Console.WriteLine("SomeMethod is runned");
        }
    }
...
Рейтинг: 0 / 0
Зависимости в MVVM в WPF
    #39618896
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
refreg,

RequerySuggested реализован через WeakEventManager, то есть с поддержкой слабых ссылок, ок, но я-то спрашивал про AddExecutedHandler.

Впрочем, курение исходника показало, что фактически подписывается на событие сам UIElement, так что в конечном итоге тоже все нормально. У меня где-то подтекает, на значит дело не в CommandManager

Код: 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.
	class Program
	{
		[STAThread]
		static void Main(string[] args)
		{
			var strongUIElement = new Grid();
			var strongSubscriber = new Subscriber();
			var strongUIElementReference = new WeakReference(strongUIElement);
			var strongSubscriberReference = new WeakReference(strongSubscriber);
			CommandManager.AddExecutedHandler(strongUIElement, strongSubscriber.SomeMethod);

			var weakUIElement = new Grid();
			var weakSubscriber = new Subscriber();
			var weakUIElementReference = new WeakReference(weakUIElement);
			var weakSubscriberReference = new WeakReference(weakSubscriber);
			CommandManager.AddExecutedHandler(weakUIElement, weakSubscriber.SomeMethod);
			weakUIElement = null;
			weakSubscriber = null;

			GC.Collect();

			Console.WriteLine(strongUIElementReference.IsAlive); // True
			Console.WriteLine(strongSubscriberReference.IsAlive); // True
			Console.WriteLine(weakUIElementReference.IsAlive); // False
			Console.WriteLine(weakSubscriberReference.IsAlive); // False
			
			Console.ReadKey();
		}

	}
...
Рейтинг: 0 / 0
38 сообщений из 38, показаны все 2 страниц
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Зависимости в MVVM в WPF
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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