|
Binding и UserControl
|
|||
---|---|---|---|
#18+
Уже второй день курим все что можно... Проблема в том что никак не могу заставить работать Binding своем контроле. Проект большой так что написал усеченный аналог с той же проблемой. Если привязать Dependency Property TheWidthHeightProperty контрола RedRectangel прямо к свойству TestWidthHeight (тип WidthHeight) в окна Window1 объекту, то квадрат размер менять не хочет хотя TestWidthHeight.Width и TestWidthHeight.Нight меняются (это видно по Labels) А если привязать свойства Width и Height контрола RedRectangel к соответствующим свойствам объекта типа WidthHeight то все в шоколаде. Но этот вариант не катит. В реальном объекте в контроле, роль которого играет RedRectangel, очень много преобразований данных для того что бы отобразить графический объект согласно данных из базы. Придется писать кучу свойств зависимости и конвертеров, а алгоритм уже работает. После нажатия на кнопку программа не приходит в OnTheWidthHeightPropertyChanged, а по задумке вроде как должна... Полный source "прикручен" к сообщению. Убрал все заголовки и объявления так как не используется ничего кроме стандартных библиотек. Итак вот код. Window1.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.
Window1.xaml.cs Код: 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.
Код: xml 1. 2. 3. 4. 5. 6.
RedRectangel.xaml.cs Код: 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.
WidthHeight.cs Код: 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.
... |
|||
:
Нравится:
Не нравится:
|
|||
08.03.2012, 16:03 |
|
Binding и UserControl
|
|||
---|---|---|---|
#18+
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsMeasure , new PropertyChangedCallback(OnPropertyChanged))); ... |
|||
:
Нравится:
Не нравится:
|
|||
08.03.2012, 21:55 |
|
Binding и UserControl
|
|||
---|---|---|---|
#18+
вместо new UIPropertyMetadata ... |
|||
:
Нравится:
Не нравится:
|
|||
08.03.2012, 21:56 |
|
Binding и UserControl
|
|||
---|---|---|---|
#18+
SeVa, у него кстати есть метод через new UIPropertyMetadata(null, OnTheWidthHeightPropertyChanged). alex_myzn , тебе надо идти самым простым путем. в студии debugging->output window -> databinding=all и dependency property=all включаешь. в своем биндинге делаешь так: Код: xml 1. 2.
и теперь смотришь output и ли immediate window и думаю, ты сразу поймешь, что к чему. обычно, когда ты юзаешь binding к user control, то он делается, раньше чем все инициализируется и ты ничего не получаешь. но у тебя может быть по другому. логи приложи в следующий раз. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.03.2012, 10:49 |
|
Binding и UserControl
|
|||
---|---|---|---|
#18+
Спасибо SeVa за ответ, тут действительно еще одна, из многих тысяч, "полочка" WPF, но к сожалению это не помогло. Я тут немного изменил программку для большей очевидности и прикрепил его к сообщению... Мне кажется что проблема лежит где-то между классом WidthHeight и свойством зависимости TheWidthHeightProperty в RedRectangel. Дело в том что изменение Width или Height в классе WidthHeight вовсе не приводит к вызову OnTheWidthHeightPropertyChanged для TheWidthHeightProperty. С одной стороны в принципе это понятно. INotifyPropertyChanged из WidthHeight отработал честно оповестив всех к привязанных в его свойствам через свойства зависимостей, что произошло изменение, это видно из работы зеленого квадрата. А вот то что касается бордового то ни кто и не говорил что изменения свойств в классе приводит к изменению свойства зависимости этого типа, т.е. ни кто не гарантирует вызов метода OnTheWidthHeightPropertyChanged в RedRectangel. А вот с другой стороны хотелось бы понять как это сделать как заставить вызываться этот метод когда произошли подобные изменения? ... |
|||
:
Нравится:
Не нравится:
|
|||
11.03.2012, 11:01 |
|
Binding и UserControl
|
|||
---|---|---|---|
#18+
Спасибо AlexeiK, Это действительно очень классный класс (прошу прощения за тавтологию). Показал он следующее: System.Windows.Data Warning: 52 : Created BindingExpression (hash=14347911) for Binding (hash=52727599) System.Windows.Data Warning: 54 : Path: 'TestWidthHeight' System.Windows.Data Warning: 57 : BindingExpression (hash=14347911): Default update trigger resolved to PropertyChanged System.Windows.Data Warning: 58 : BindingExpression (hash=14347911): Attach to TestBinding.RedRectangel.TheWidthHeight (hash=51393439) System.Windows.Data Warning: 63 : BindingExpression (hash=14347911): Resolving source System.Windows.Data Warning: 66 : BindingExpression (hash=14347911): Found data context element: <null> (OK) System.Windows.Data Warning: 70 : Lookup name TheControl: queried StackPanel (hash=26756241) System.Windows.Data Warning: 74 : BindingExpression (hash=14347911): Activate with root item Window1 (hash=23264094) System.Windows.Data Warning: 104 : BindingExpression (hash=14347911): At level 0 - for Window1.TestWidthHeight found accessor RuntimePropertyInfo(TestWidthHeight) System.Windows.Data Warning: 100 : BindingExpression (hash=14347911): Replace item at level 0 with Window1 (hash=23264094), using accessor RuntimePropertyInfo(TestWidthHeight) System.Windows.Data Warning: 97 : BindingExpression (hash=14347911): GetValue at level 0 from Window1 (hash=23264094) using RuntimePropertyInfo(TestWidthHeight): WidthHeight (hash=14303791) System.Windows.Data Warning: 76 : BindingExpression (hash=14347911): TransferValue - got raw value WidthHeight (hash=14303791) System.Windows.Data Warning: 85 : BindingExpression (hash=14347911): TransferValue - using final value WidthHeight (hash=14303791) Вроде все в норме. До этого тоже не было ошибок с binding. Кстати я знаю что надо создавать WidthHeight до InitializeComponent(). Именно в этот момент и вызывается OnTheWidthHeightPropertyChanged тот единственный раз, так как произошло изменение самого объекта. Именно в этот момент квадраты становятся 50х50. А дальше ничего... :-( Я не нашел где устанавливаются опции о которых ты говорил AlexeiKSeVa, в студии debugging->output window -> databinding=all и dependency property=all включаешь. в tools -> options -> debugging ничего подобного нет. У меня VS2008 SP1. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.03.2012, 11:47 |
|
Binding и UserControl
|
|||
---|---|---|---|
#18+
alex_myznСпасибо SeVa за ответ, тут действительно еще одна, из многих тысяч, "полочка" WPF, но к сожалению это не помогло. Я тут немного изменил программку для большей очевидности и прикрепил его к сообщению... Мне кажется что проблема лежит где-то между классом WidthHeight и свойством зависимости TheWidthHeightProperty в RedRectangel. Дело в том что изменение Width или Height в классе WidthHeight вовсе не приводит к вызову OnTheWidthHeightPropertyChanged для TheWidthHeightProperty. С одной стороны в принципе это понятно. INotifyPropertyChanged из WidthHeight отработал честно оповестив всех к привязанных в его свойствам через свойства зависимостей, что произошло изменение, это видно из работы зеленого квадрата. А вот то что касается бордового то ни кто и не говорил что изменения свойств в классе приводит к изменению свойства зависимости этого типа, т.е. ни кто не гарантирует вызов метода OnTheWidthHeightPropertyChanged в RedRectangel. А вот с другой стороны хотелось бы понять как это сделать как заставить вызываться этот метод когда произошли подобные изменения? Вполне ожидаемое поведение. При сеттерах WidthHeight выдается сообщение об изменении конкретного свойства, а не всего объекта, к которому делается связывание в красном прямоугольнике. Не совсем понятно для чего нужен подобный сценарий, решений может быть несколько: - в OnTheWidthHeightPropertyChanged задавать нужные binding'и, а не делать изменения значений - создать behavior, в OnAttached задавать нужные связывания ... |
|||
:
Нравится:
Не нравится:
|
|||
11.03.2012, 12:21 |
|
Binding и UserControl
|
|||
---|---|---|---|
#18+
SeVa- в OnTheWidthHeightPropertyChanged задавать нужные binding'и, а не делать изменения значений Этот вариант не подходит та как именно OnTheWidthHeightPropertyChanged и не вызывается и что бы внутри него не написать все равно работать не будет. SeVa- создать behavior, в OnAttached задавать нужные связывания Это весьма интересно, но из того что я успел найти в MSDN пока ничего не понятно. Может есть ссылка на пример? Я тут попробовал обойти это... В классе WidthHeight создал свойство MirrorWidthHeight которое указывает на сам объект: Код: 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.
и привязался к нему... Код: xml 1.
Но это тоже не возымело действия. Хотя почему, уже совсем не очевидно. OnTheWidthHeightPropertyChanged не вызывается ни в какую, хотя привязка уже осуществляется на свойство WidthHeight... Далее планирую следующий подход. Пробую написать еще один вариант с wraper для WidthHeight и вызовом PropertyChanged через событие изменения содержимого wraper... Да... Вот новый вариант программки. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.03.2012, 12:57 |
|
Binding и UserControl
|
|||
---|---|---|---|
#18+
Упс... забыл файлик ... |
|||
:
Нравится:
Не нравится:
|
|||
11.03.2012, 12:59 |
|
Binding и UserControl
|
|||
---|---|---|---|
#18+
Есть Expression Blend SDK. Примеры для него ... |
|||
:
Нравится:
Не нравится:
|
|||
11.03.2012, 13:05 |
|
Binding и UserControl
|
|||
---|---|---|---|
#18+
SeVaНе совсем понятно для чего нужен подобный сценарий Я описал почему мы пошли по этому пути. alex_myznВ реальном объекте в контроле, роль которого играет RedRectangel, очень много преобразований данных (в том числе и 3D) для того что бы отобразить графический объект согласно данных из базы. Придется писать кучу свойств зависимости и конвертеров, а алгоритм уже работает. хотя конечно это правильный подход... PS Да тут нашел очень простой способ который решил бы все проблемы... (это из реального проекта) Код: c# 1. 2. 3.
Но честное слово это все ламерством попахивает... ... |
|||
:
Нравится:
Не нравится:
|
|||
11.03.2012, 13:09 |
|
Binding и UserControl
|
|||
---|---|---|---|
#18+
SeVaЕсть Expression Blend SDK. Примеры для него Огромное спасибо вам за то что е жалеете время что бы мне помочь. Я так и понял когда начал читать про behaviors. Это все для Framework 4, да и Expression 4-й нужен, с практической точки зрения это на данном этапе невозможно реализовать. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.03.2012, 13:17 |
|
Binding и UserControl
|
|||
---|---|---|---|
#18+
Пока вопрос остается открытым... ... |
|||
:
Нравится:
Не нравится:
|
|||
11.03.2012, 14:14 |
|
Binding и UserControl
|
|||
---|---|---|---|
#18+
Blend SDK for Net 3.5 . Одного вызова OnTheWidthHeightPropertyChanged вполне достаточно, чтобы сделать нужные binding'и (SetBinding), тогда все изменения будут отслеживаться на автомате. Но, судя по примеру из реального проекта с DataContext, нужно еще отслеживание изменения всего объекта, это можно сделать отслеживая событие DataContextChanged. Но если приходится извращаться, то это говорит о том, что решение не в духе wpf. Суть всей затеи непонятна, совершенно непрозрачен показанный вариант с RedRectangel. Этот функционал можно просто реализовать с помощью неявных или явных шаблонов для WidthHeight без всяких мультиков. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.03.2012, 14:56 |
|
Binding и UserControl
|
|||
---|---|---|---|
#18+
Следуйте принципам MVVM и все будет проще Код: 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.
PS Для сложной логики самое место - ViewModel ... |
|||
:
Нравится:
Не нравится:
|
|||
11.03.2012, 16:10 |
|
Binding и UserControl
|
|||
---|---|---|---|
#18+
SeVaОдного вызова OnTheWidthHeightPropertyChanged вполне достаточно, чтобы сделать нужные binding'и (SetBinding), тогда все изменения будут отслеживаться на автомате. А почему же они не отслеживаются когда binding сделан непосредственно в XAML? Уж куда проще то... На счет DataContext, это я так привел, для примера, решение со сбросом DataContext, заполнением из базы и последующим заполнением из базы считаю неправильным, та как согласно технологии WPF Binding именно и предназначен для того сто бы разные объекты смотря на одни и те же данные имели одинаковые значения и обновлялись не зависимо от того кто из них или вообще некое внешнее воздействие привело к обновлению данных. Кстати сам Control не влияет на дату, редактирование происходит в другом месте. Данные записываются в некую иерархическую коллекцию (она то и есть DataContext), один из пунктов которой и есть информация для Control. Так вот после этих изменений и возникает необходимость обновить сам Control. SeVaСуть всей затеи непонятна, совершенно непрозрачен показанный вариант с RedRectangel. Этот функционал можно просто реализовать с помощью неявных или явных шаблонов для WidthHeight без всяких мультиков. Это просто пример иллюстрирующий проблему. RedRectangel это просто некий UserControl, на самом деле он довольно сложный и свойств у него несколько десятков. Кнопки (мультики) призваны что бы воздействовать на данные. И причем здесь шаблоны я вообще не понимаю. Та что я не совсем понял что вы имеете ввиду. SeVaСледуйте принципам MVVM и все будет проще Вот им то я и стараюсь следовать. Все решается через Binding и DependencyProperty. Данные в отдельном классе (WidthHeight) визуальное представление в отдельном (RedRectangel) . Бизнес логика в отдельном.(Window1). Все связи через Binding и DependencyProperty. Может конечно я что-то не так понимаю в MVVM. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.03.2012, 16:43 |
|
Binding и UserControl
|
|||
---|---|---|---|
#18+
Кстати попытка написать Wrapper тоже потерпела фиаско. Ну не хочет он дергать этот чертов OnTheWidthHeightPropertyChanged!!!! ... |
|||
:
Нравится:
Не нравится:
|
|||
11.03.2012, 16:47 |
|
Binding и UserControl
|
|||
---|---|---|---|
#18+
alex_myzn, запустил твой пример. работает. Код: xml 1.
вот этот биндинг работает. я меняю в коде c 50,50 на 100,100 и при запуске вижу 100, 100 или 50,50. ты этого хотел достичь? ... |
|||
:
Нравится:
Не нравится:
|
|||
11.03.2012, 17:27 |
|
Binding и UserControl
|
|||
---|---|---|---|
#18+
AlexeiK, Очень странно... Именно этот binding у меня и не работает. Алексей скажите а какой из 2-х квадратов работает, красный или зеленый? У меня работает зеленый. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.03.2012, 18:21 |
|
Binding и UserControl
|
|||
---|---|---|---|
#18+
alex_myzn, слушай, я тут просто разобрался. ты хочешь чтобы изменяя локальную переменную в window , изменялись параметры ширина и длина прямоугольников. ну хорошо это правильное желание. токо ты забыл, про то, что window должна реализовать inotifypropertychanged , чтобы дать понять все, что TestWidthHeight изменилась. Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9.
далее делаем так. и все работает. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.03.2012, 18:47 |
|
Binding и UserControl
|
|||
---|---|---|---|
#18+
приложу файл ... |
|||
:
Нравится:
Не нравится:
|
|||
11.03.2012, 18:48 |
|
Binding и UserControl
|
|||
---|---|---|---|
#18+
alex_myzn, то есть, оповестить о том, что свойство изменилось удается через NEW. а через inotifypropertychanged не удается. не знаю, мож у тебя косяк в коде где. слолжно на c# читать. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.03.2012, 18:49 |
|
Binding и UserControl
|
|||
---|---|---|---|
#18+
alex_myzn, Gосмотрел я твой код. Запускал проект TestBinding. В ркасном квадрате ты изменяешь свойства Width и Height. Это встроенные свойства зависимостей объекта Rectangle. А как ты должен знать - привязка без проблем работает со свойствами зависимостей. Поэтому реализовав интерфейс INot - свойства Width и Height (как свойства зависимостей) видят эти изменение, которые ты делаешь через кнопки. Теперь что касается красного квадрата. Ты пытаешься привязать к свойству TheWidthHeight - TestWidthHeight.MirrorWidthHeight. При этом TestWidthHeight.MirrorWidthHeight реализует интерфейс INot - поэтому он передает эти изменения свойству TheWidthHeight. НО... свойство TheWidthHeight не является свойством зависимостей (ты его таким не объявил). Поэтому не удивительно, что красный квадрат у тебя не изменяется. Объяви TheWidthHeight как свойство зависимостей и у тебя все взлетит ... |
|||
:
Нравится:
Не нравится:
|
|||
11.03.2012, 21:07 |
|
Binding и UserControl
|
|||
---|---|---|---|
#18+
alex_myzn, Чуть подправил предыдущее свое сообщение: Посмотрел я твой код. Запускал проект TestBinding. В зеленом квадрате ты изменяешь свойства Width и Height. Это встроенные свойства зависимостей объекта Rectangle. А как ты должен знать - привязка без проблем работает со свойствами зависимостей. Поэтому реализовав интерфейс INot - свойства Width и Height (как свойства зависимостей) видят эти изменение, которые ты делаешь через кнопки. Теперь что касается красного квадрата. Ты пытаешься привязать к свойству TheWidthHeight - TestWidthHeight.MirrorWidthHeight. При этом TestWidthHeight.MirrorWidthHeight реализует интерфейс INot - поэтому он передает эти изменения свойству TheWidthHeight. НО... свойство TheWidthHeight не является свойством зависимостей (ты его таким не объявил), соответственно это свойство не может видеть подаваемые ему изменения. Поэтому не удивительно, что красный квадрат у тебя не изменяется. Объяви TheWidthHeight как свойство зависимостей и у тебя все взлетит ... |
|||
:
Нравится:
Не нравится:
|
|||
11.03.2012, 21:10 |
|
Binding и UserControl
|
|||
---|---|---|---|
#18+
unknownfromrus, унего же объявлено оно. Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9.
ты чтото, не внимательно смотрел. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.03.2012, 22:12 |
|
|
start [/forum/topic.php?fid=21&fpage=42&tid=1441895]: |
0ms |
get settings: |
9ms |
get forum list: |
12ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
33ms |
get topic data: |
13ms |
get forum data: |
2ms |
get page messages: |
65ms |
get tp. blocked users: |
2ms |
others: | 336ms |
total: | 480ms |
0 / 0 |