|
Привязка DP-свойства UserControl к вложенному элементу
|
|||
---|---|---|---|
#18+
Хотел реализовать одну задачу (в учебно-обучающих целях). Для реализации потребовалось создать привязку DP-свойства UserControl ко вложенному элементу. До этого привязывал вложенный элемент к свойству UC - проблем не было. В данном случае привязка в элементе используется для другой зависимости (для связи с VM). Поэтому привязку надо создать у свойства UC. И тут я "впал в ступор". Как раньше делал не получается. В XAML это свойство на уровне UC не видно. Делаю привязку в коде - не работает. Чего-то не догоняю. Ниже пример. В целом внутри UC хочу (если такое возможно) сделать такую цепочку привязок. VM -> свойство UI элемента -> DP свойство UC. Привязку надо сделать от свойства Result UC к свойству TextBox.Text элемента "tbResult". В CB UC моя попытка (не рабочая) программного создания привязки. 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.
CB Код: 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.
На всякий случай, если понадобится интерфейс и его реализация Интерфейс ICalculator Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
Его реализация Код: 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.
Также если понадобится основное окно и VM Основное окно Код: xml 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23.
Основная (родительская) VM Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
Также прилагаю архив проекта ... |
|||
:
Нравится:
Не нравится:
|
|||
13.04.2019, 16:39 |
|
Привязка DP-свойства UserControl к вложенному элементу
|
|||
---|---|---|---|
#18+
Желание само по себе странное и кривое. Но если в учебных целях - скажи, как ты проверяешь в проекте, что установленный байндинг не работает (что нажимать и куда смотреть), я посмотрю почему. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.04.2019, 17:05 |
|
Привязка DP-свойства UserControl к вложенному элементу
|
|||
---|---|---|---|
#18+
Shocker.ProЖелание само по себе странное и кривое. Но если в учебных целях - скажи, как ты проверяешь в проекте, что установленный байндинг не работает (что нажимать и куда смотреть), я посмотрю почему. Цель показать разные способы передачи данных между UC и View и их плюсы и минусы. То что не работает именно привязка, проверял в дебаге. При изменени tbResult.Text в сеттер свойства UC.Result нет вхождения. В целом по реализации при изменении tbResult.Text по привязке должно изменится UC.Result, а к нему привязанное в View свойство VM.ResultMain, к которому привязан TextBlock в View, который и должен отобразить результат. Общая цепочка привязок такая: "VM UC (VM.VMfromUC) свойство Result" <- "UC tbResult.Text" <- "UC DP-свойство Result" = "View DPCalculatorUC.Result" -> "VM View свойство ResultMain" <- "View TextBlock Run.Text". В VM (VM.VMfromUC) самого UC всё привязано и работает как задумывалось. Нет привязки именно между UC.Result и tbResult.Text. То что с этим проблемы, я сразу понял когда попытался сделать привязку в XAML. В XAML на уровне UC его свойства Result не видно. Может я его неправильно объявляю? Но вложенные элементы без проблем привязываются к этому свойству. Допустим такая привязка работает нормально Код: xml 1. 2. 3.
Но тогда я не знаю как сделать привязку этого же свойства к UC.DataContext.Result P.S. Что касается кривости. У меня пока реализовано ещё два примера связи на уровне Модели и на уровне VM. Хотел показать на уровне View через DP свойство. И споткнулся. Если можете опишите, возможные решения для подобной задачи и их + и -. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.04.2019, 18:31 |
|
Привязка DP-свойства UserControl к вложенному элементу
|
|||
---|---|---|---|
#18+
Eld Haspв сеттер свойства UC.Result нет вхождения.для начала. В сеттер вхождения НЕ БУДЕТ в любом случае. Привязка для свойств зависимости работает через DependencyObject.SetValue - надо это четко знать. В принципе - геттер и сеттер для свойства зависимости можно ВООБЩЕ НЕ СОЗДАВАТЬ, это делается только для удобства программиста ... |
|||
:
Нравится:
Не нравится:
|
|||
13.04.2019, 18:56 |
|
Привязка DP-свойства UserControl к вложенному элементу
|
|||
---|---|---|---|
#18+
Eld Hasp P.S. Что касается кривости. У меня пока реализовано ещё два примера связи на уровне Модели и на уровне VM. Хотел показать на уровне View через DP свойство. И споткнулся. Если можете опишите, возможные решения для подобной задачи и их + и -.Идеологически. Юзерконтрол не должен работать в контексте некоей внешней VM (внешнего датаконтекста). Это должен быть автономный модуль, который получает все данные для своей работы через свойства зависимости, определенные на уровне юзерконтрола. Внутри он может использовать свою вьюмодельку, но я, в конце-концов, отказался от такого подхода - он только запутывает, необходимые поля задаются либо напрямую через codebehind, либо через RelativeSource UserControl. А вот такое:Eld HaspОбщая цепочка привязок такая: "VM UC (VM.VMfromUC) свойство Result" <- "UC tbResult.Text" <- "UC DP-свойство Result" = "View DPCalculatorUC.Result" -> "VM View свойство ResultMain" <- "View TextBlock Run.Text".это слишком суровая жесть, ты и сам в ней разобраться не можешь. Такие цепочки - зло для масштабирования и отладки. Делай всё как можно проще. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.04.2019, 19:04 |
|
Привязка DP-свойства UserControl к вложенному элементу
|
|||
---|---|---|---|
#18+
Eld Haspа к нему привязанное в View свойство VM.ResultMain, к которому привязан TextBlock в View, который и должен отобразить результат.Еще раз. Расскажи мне как пользователю - я запустил твой проект - какие кнопки я должен нажать и где должен увидеть результат и какой. Делать реверс-инжиниринг всего твоего кода и проецировать на невнятное описание на форуме у меня желания нет, но можно посмотреть конкретную проблему. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.04.2019, 19:06 |
|
Привязка DP-свойства UserControl к вложенному элементу
|
|||
---|---|---|---|
#18+
Shocker.ProEld Haspв сеттер свойства UC.Result нет вхождения.для начала. В сеттер вхождения НЕ БУДЕТ в любом случае. Привязка для свойств зависимости работает через DependencyObject.SetValue - надо это четко знать. В принципе - геттер и сеттер для свойства зависимости можно ВООБЩЕ НЕ СОЗДАВАТЬ, это делается только для удобства программистаВот это не до понял.... Вернее, вроде читал и понял, но на практике как оказалось - туплю... Как можно проверить работу привязки? В "Динамическом обозревателе свойств" в свойстве DPCalculatorUC.Result BindingExpression, но вычисленное значение 0. Может я не правильно программно задаю привязку? ... |
|||
:
Нравится:
Не нравится:
|
|||
13.04.2019, 19:27 |
|
Привязка DP-свойства UserControl к вложенному элементу
|
|||
---|---|---|---|
#18+
Eld HaspКак можно проверить работу привязки?Если хочется поставить точку останова, то добавь PropertyChangedCallback в объявление свойства ... |
|||
:
Нравится:
Не нравится:
|
|||
13.04.2019, 19:30 |
|
Привязка DP-свойства UserControl к вложенному элементу
|
|||
---|---|---|---|
#18+
Shocker.ProEld Haspа к нему привязанное в View свойство VM.ResultMain, к которому привязан TextBlock в View, который и должен отобразить результат.Еще раз. Расскажи мне как пользователю - я запустил твой проект - какие кнопки я должен нажать и где должен увидеть результат и какой. Делать реверс-инжиниринг всего твоего кода и проецировать на невнятное описание на форуме у меня желания нет, но можно посмотреть конкретную проблему. В первом окне выбирается двойным кликом пример. В данном случае это последний "Взаимодействие по схеме: DP свойство UserControl -> "родительская VM" После запуска примера два маленькое окошко. UC - это два TextBox для ввода операндов, ComboBox для выбора оператора и после знака равенства TextBох для результата. Над этим UC один TextBox из самого окна с текстом "Результат вычисления:" после него должен выводится тот же результат, что и в TextBox для результата в UC. Визуально этот пример работает полностью идентично двум верхним: "Взаимодействие по схеме: "вложенная VM" -> Model -> "родительская VM" и "Взаимодействие по схеме: "вложенная VM" -> "родительская VM" ... |
|||
:
Нравится:
Не нравится:
|
|||
13.04.2019, 19:36 |
|
Привязка DP-свойства UserControl к вложенному элементу
|
|||
---|---|---|---|
#18+
Shocker.ProЮзерконтрол не должен работать в контексте некоей внешней VM (внешнего датаконтекста). Это должен быть автономный модуль, который получает все данные для своей работы через свойства зависимости, определенные на уровне юзерконтрола. Внутри он может использовать свою вьюмодельку, но я, в конце-концов, отказался от такого подхода - он только запутывает, необходимые поля задаются либо напрямую через codebehind, либо через RelativeSource UserControl. А вот такое:Eld HaspОбщая цепочка привязок такая: "VM UC (VM.VMfromUC) свойство Result" <- "UC tbResult.Text" <- "UC DP-свойство Result" = "View DPCalculatorUC.Result" -> "VM View свойство ResultMain" <- "View TextBlock Run.Text".это слишком суровая жесть, ты и сам в ней разобраться не можешь. Такие цепочки - зло для масштабирования и отладки. Делай всё как можно проще. Была идея реализовать (в показательных целях) UC для вычисления одной операции над двумя операндами. Список операций и вычисления производятся в VM (с интерфейсом ICalculator). В UC все привязки только к этой своей собственной VM. Эта VM может быть любой и передаётся в UC через DataContext от вышестоящего элемента. В двух примерах передача данных из VM UC осуществлялась из этой VM. В третьем хотел показать как замкнуть эту передачу на уровне View через дополнительное внешнее DP-свойство UC чтобы обойтись без явного подключения обработчиков событий в основной VM. На мой взгляд, я в принципе, и сделал как Вы пишите: "Юзерконтрол не должен работать в контексте некоей внешней VM (внешнего датаконтекста). Это должен быть автономный модуль, который получает все данные для своей работы через свойства зависимости, определенные на уровне юзерконтрола. Внутри он может использовать свою вьюмодельку" Вот только не получается так же вернуть полученный результат. Цепочка привязок просто выглядит так ужасно, потому что полностью развёрнуто. Но каждый её кусочек действует независимо от других. На уровне UC инкапсулирована эта часть "VM UC (VM.VMfromUC) свойство Result" <- "UC tbResult.Text" <- "UC DP-свойство Result" . Всего две привязки - ничего не обычного. На уровне View также только две привязки "View DPCalculatorUC.Result" -> "VM View свойство ResultMain" <- "View TextBlock Run.Text". Сделать так: "необходимые поля задаются либо напрямую через codebehind, либо через RelativeSource UserControl"... Честно говоря не знаю как. По идее список операций и действия по ним измеряемы, и определятся передаваемой локальной VM. Как обойтись без неё - не могу понять. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.04.2019, 19:57 |
|
Привязка DP-свойства UserControl к вложенному элементу
|
|||
---|---|---|---|
#18+
Ты одновременно пытаешься установить одно и то же свойство в коде и в XAML Код: xml 1.
Код: c# 1.
... |
|||
:
Нравится:
Не нравится:
|
|||
13.04.2019, 20:04 |
|
Привязка DP-свойства UserControl к вложенному элементу
|
|||
---|---|---|---|
#18+
Eld HaspБыла идея реализовать (в показательных целях) UC для вычисления одной операции над двумя операндами. Список операций и вычисления производятся в VM (с интерфейсом ICalculator). В UC все привязки только к этой своей собственной VM. Эта VM может быть любой и передаётся в UC через DataContext от вышестоящего элемента.Сделай у своего юзерконтрола свойство с типом ICalculator. Таким образом ты сможешь общаться с моделью калькулятора и из XAML и из codebehind ... |
|||
:
Нравится:
Не нравится:
|
|||
13.04.2019, 20:07 |
|
Привязка DP-свойства UserControl к вложенному элементу
|
|||
---|---|---|---|
#18+
Shocker.ProТы одновременно пытаешься установить одно и то же свойство в коде и в XAML Код: xml 1.
Код: c# 1.
Да, пытаюсь. Но не думал что привязка внутри UC будет конфликтовать с привязкой снаружи. Значит это опять моё недопонимание работы DP-свойств. А как тогда можно обойти это? Как связать DataContext.Result, tbResult.Text и UC.ResultMain? Если нельзя внутри использовать привязку ResultMain, то у меня фантазия иссякает... Подвесить обработчик PropertyChanged на DatContext? Но что потом делать. Ведь прямое присвоение значения свойству tbResult.Text тоже разрушит привязку. Чё-то я влез в какой-то тупик... Или свойство VM Result сделать DP-свойством? Но тогда теряется наглядность... ... |
|||
:
Нравится:
Не нравится:
|
|||
13.04.2019, 20:21 |
|
Привязка DP-свойства UserControl к вложенному элементу
|
|||
---|---|---|---|
#18+
Eld HaspДа, пытаюсь. Но не думал что привязка внутри UC будет конфликтовать с привязкой снаружи. Значит это опять моё недопонимание работы DP-свойств.Это ОДНО И ТО ЖЕ свойство, а не два разных ... |
|||
:
Нравится:
Не нравится:
|
|||
13.04.2019, 20:22 |
|
Привязка DP-свойства UserControl к вложенному элементу
|
|||
---|---|---|---|
#18+
Shocker.ProEld HaspБыла идея реализовать (в показательных целях) UC для вычисления одной операции над двумя операндами. Список операций и вычисления производятся в VM (с интерфейсом ICalculator). В UC все привязки только к этой своей собственной VM. Эта VM может быть любой и передаётся в UC через DataContext от вышестоящего элемента.Сделай у своего юзерконтрола свойство с типом ICalculator. Таким образом ты сможешь общаться с моделью калькулятора и из XAML и из codebehind Да, это не проблема. VM можно получить и из DataContext. Проблема, как я писал выше, в том как потом записать полученное из VM значение в UI элемент. При прямой записи разрушаются же привязки. Вроде бы... Надо поэксперементировать. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.04.2019, 20:25 |
|
Привязка DP-свойства UserControl к вложенному элементу
|
|||
---|---|---|---|
#18+
Eld HaspА как тогда можно обойти это?Ты сделал неимоверно сложную архитектуру для такой простой задачи. Как я уже сказал - у тебя есть юзерконтрол для калькулятора и есть модель калькулятора. Поскольку модель калькулятора для юзерконтрола поставляется снаружи - задавай ее через свойство ICalculator юзерконтрола. Таким образом ты сможешь к этой модели обращаться - из XAML юзерконтрола - через relative source - из XAML основного окна - через поле основной модели - из codebegind юзерконтрола через свойство юзерконтрола - из основной модели - через поле модели Это будет прозрачно, понятно и без бешеных цепочек байндингов ... |
|||
:
Нравится:
Не нравится:
|
|||
13.04.2019, 20:27 |
|
Привязка DP-свойства UserControl к вложенному элементу
|
|||
---|---|---|---|
#18+
Shocker.ProEld HaspДа, пытаюсь. Но не думал что привязка внутри UC будет конфликтовать с привязкой снаружи. Значит это опять моё недопонимание работы DP-свойств.Это ОДНО И ТО ЖЕ свойство, а не два разных Да, я уже понял. Туплю из-за недопонимания. Какой-то мультибиндинг, что ли сделать? Но блин, это, по моему, значительно усложняет пример. А в голову ничего простого не приходит. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.04.2019, 20:28 |
|
Привязка DP-свойства UserControl к вложенному элементу
|
|||
---|---|---|---|
#18+
Eld HaspПроблема, как я писал выше, в том как потом записать полученное из VM значение в UI элемент. При прямой записи разрушаются же привязки. Вроде бы...И фиг бы с ними. Я же говорил - не надо работать изнутри юзерконтрола с датаконтекстом, определенным вне юзерконтрола ... |
|||
:
Нравится:
Не нравится:
|
|||
13.04.2019, 20:29 |
|
Привязка DP-свойства UserControl к вложенному элементу
|
|||
---|---|---|---|
#18+
Eld HaspКакой-то мультибиндинг, что ли сделать? Но блин, это, по моему, значительно усложняет пример.сделай как сказал я, и ты поймешь, насколько всё станет проще ... |
|||
:
Нравится:
Не нравится:
|
|||
13.04.2019, 20:30 |
|
Привязка DP-свойства UserControl к вложенному элементу
|
|||
---|---|---|---|
#18+
Eld HaspПроблема, как я писал выше, в том как потом записать полученное из VM значение в UI элемент. При прямой записи разрушаются же привязки. Вроде бы...ВСЕ UI-элементы привяжи к VM, а не друг к другу ... |
|||
:
Нравится:
Не нравится:
|
|||
13.04.2019, 20:32 |
|
Привязка DP-свойства UserControl к вложенному элементу
|
|||
---|---|---|---|
#18+
Shocker.ProEld HaspА как тогда можно обойти это?Ты сделал неимоверно сложную архитектуру для такой простой задачи. Как я уже сказал - у тебя есть юзерконтрол для калькулятора и есть модель калькулятора. Поскольку модель калькулятора для юзерконтрола поставляется снаружи - задавай ее через свойство ICalculator юзерконтрола. Таким образом ты сможешь к этой модели обращаться - из XAML юзерконтрола - через relative source - из XAML основного окна - через поле основной модели - из codebegind юзерконтрола через свойство юзерконтрола - из основной модели - через поле модели Это будет прозрачно, понятно и без бешеных цепочек байндингов Ок! У меня как бы примеры построены по цепочке. В предыдущих темах (в общем цикле) я показывал как сделать этот же калькулятор с использованием INPC в MVVM, конвертеров, WPF команд. Сейчас как бы перехожу от реализации в последней теме к различным способом реализации того же в виде UC. На предыдущих примерах я показывал как это сделать использую VM UC. В том числе не прямо Ваш вариант, но очень близкий. Может ещё дополню и Вашим вариантом. На этом примере хотел сделать имеено передачу результата через DP свойство UC. Почему? Представим теперь следующий шаг-пример (после того который обсуждаем здесь). Та логика которая сейчас поставляется из подключаемой VM будет инкапсулирована внутри UC (ведь пример учебный и это может быть не обязательно калькулятор). И View ни чего об этой вложенной VM знать не будет. Самое логичное тогда, связать VM и UC через DP свойство UC. Но, блин! Опять возникает та проблема которую я не могу решить здесь! Мне придётся или придумывать какое-то решение, или менять план задуманной мною темы. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.04.2019, 20:45 |
|
Привязка DP-свойства UserControl к вложенному элементу
|
|||
---|---|---|---|
#18+
Shocker.ProEld HaspДа, пытаюсь. Но не думал что привязка внутри UC будет конфликтовать с привязкой снаружи. Значит это опять моё недопонимание работы DP-свойств.Это ОДНО И ТО ЖЕ свойство, а не два разныхТолько сегодня до меня дошло, что в принципе по алгоритму у свойства UC.Result не должно быть публичного сеттера. Это же свойство для возврата результата, а не его получения. И тогда сразу всё встаёт на свои места. Так как в View становится невозможным сделать у него привязку. А привязки на него работают нормально. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.04.2019, 09:39 |
|
Привязка DP-свойства UserControl к вложенному элементу
|
|||
---|---|---|---|
#18+
А есть ли возможность при объявленииDependencyProperty явно указать какие режимы (Mode) привязки можно использовать? Что бы запретить все кроме OneWayToSource. Свойство только для чтения DependencyProperty.RegisterReadOnly(...) не подходит, так к нему нельзя сделать ни какую привязку. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.04.2019, 10:45 |
|
Привязка DP-свойства UserControl к вложенному элементу
|
|||
---|---|---|---|
#18+
вроде бы нет ... |
|||
:
Нравится:
Не нравится:
|
|||
14.04.2019, 11:00 |
|
Привязка DP-свойства UserControl к вложенному элементу
|
|||
---|---|---|---|
#18+
Сделал пока так - до большего (если это возможно) пока не додумался. CB UC Код: 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.
XAML UC Код: 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.
XAML View Код: 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.
... |
|||
:
Нравится:
Не нравится:
|
|||
14.04.2019, 11:30 |
|
|
start [/forum/topic.php?fid=21&msg=39800951&tid=1440340]: |
0ms |
get settings: |
10ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
46ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
56ms |
get tp. blocked users: |
1ms |
others: | 251ms |
total: | 397ms |
0 / 0 |