WPF: Привязка данных к глубоко вложенному свойству
Возможно ли силами XAML привязать TexBlock'у значение свойства объекта, который глубоко вложен?
К примеру, TextBlock находится в ProgramName.MainWindow, а привязываемое свойство в ProgramName.App.Object1.Object2.Object3.Value.
На самом деле, я не могу понять как можно указать в XAML, что объект находится в определенном пространстве имен.
Пытался играться с DataContext и xmlns, но все бестолку.
В интернетах все примеры для простых вариантов привязки. :(
Да, я так именно и делал в коде. Так работает, но хотелось бы в XAML и чтобы для разных объектов разные DataContext. Хотя мне на одном форуме написали, что, вероятно. нельзя. Т.е. нужно черз код обзательно, а не через разметку.
DataContext — это объект, и ставить его надо из кода (это хорошая практика, так делать рекомендуется). Разные DataContext разным объектам (что имеется ввиду под объектом?) ставить можно и из кода.
Даже не пытайтесь ставить DataContext не из кода. Лучше в таком случае объясните что вас сподвигло на такую идею — уверен для этого есть более правильное решение.
На форуме лукавят, поставить DataContext можно и из разметки (можно, но нужно ли?), но учитывая то, что DataContext — это объект, то его еще как-то надо получить, соотв. если ни один DataContext не устанавливается в коде и все объекты DataContext не являются членами визуальных элементов, то единственный путь — пристыковать все объекты DataContext как статические свойства каких-либо классов — но это очевидный костыль.
Просто не знаю как еще поступить. Есть куча разных модулей программы в виде объектов. Эти объекты создаются в конструкторе в главном объекте приложения App (тип Application) и там используются. Нужно как-то выводить и задавать свойства таких объектов через графический интерфейс, сделанный на WPF.
Странно, но так не работает. App к DataContext не присваивается, так как класс, а при присваивание «this», просто ничего не отображается в TextBlock. TextBlock Text="{Binding Path=Log.LastEntryText}"
Кстати, вот так работает, но это задание DataContext напрямую к объекту лога, что неприемлимо.
Window_Loading win_loading = new Window_Loading();
win_loading.DataContext = this.Log;
win_loading.Show();
Вообще практика присваивать App в качестве DataContext — очень плохая, т.к. DataContext — это ViewModel (Ну или Controller/Presenter), а объект приложения никак не годится на эту роль — это очень жесткий гвоздь в архитектуре.
Хотя формально все должно работать, если Log — публичное свойство App и вся иерархия инициализированна на момент срабатывания привязок.
ProgramName.(AppType.App).(Object1Type.Object1).(Object2Type.Object2).(Object3Type.Object3).Value
Примерно так попробуйте… Самому сейчас лень проверять, но должно выглядеть примерно так…
Что-то не очень понял что тут. Если что, у меня класс не статический, а Log и App — объекты.
Попробовал по аналогии написать. Задал вот такой xmlns: xmlns:log="clr-namespace:MainProgram.App.Log;assembly=MainProgram"
Пишет: Незаданное пространство имен CLR. URI «clr-namespace» ссылается на пространство имен «MainProgram.App.Log», которое не включено в сборку.
К объектам надо как-то получить доступ — или через статический объект, или через объект, который можно получить из байндинга — напр. DataContext, родительские контейнеры и т.д. А пространство имен — это именно пространство имен, то что namespace в сборке.
Через что вы хотите получить доступ к объекту?
Что-то меня эти статические объекты смущают. Не понимаю зачем они и как мне выкрутиться, если у меня все объекты нестатические. Попробовал вот так: TextBlock Text="{Binding Source={x:Static local:App.Log.LastLogEntry}, Mode=OneWay}"
Пишет:
не удается найти тип «App.Log». Имена типов вводятся с учетом регистра букв.
и
Не удалось создать экземпляр типа «StaticExtension».
local — 'это: xmlns:local=«clr-namespace:MainProgram»
MainProgram — пространство имен основное.
App — объект приложения (нестатический).
Log — объект логирования (нестатический).
LastLogEntry — стркоа внутри Log, содержащая последнюю запись в лог (нестатическая).
Я предлагаю выложить код на PasteBin или аналогичный сервис, в частности — файлы app.xaml, app.cs, файлы основной формы с привязкой (xaml, cs), иерархию до того поля, которое вы хотите привязать и место, где создается объект (если он не статический), глубоко вложенное свойство от которого вы хотите привязать.
А вообще (если смотреть по хорошему) — таких глубоких привязок просто не должно быть.
Если у вас объекты нестатические — вы обязаны иметь точку, которую можно получить из привязки (DataContext или свойства элемента, или свойства родителей, или через другой статический объект), из которой можно получить ссылку на требуемый нестатический объект.