Здравствуйте, MxMsk, Вы писали:
MM>>Примерно так и есть: либо дефолтное в метаданных, либо отдельное значение в паре с приоритетом. MM>Надо добавить, что есть еще один уровень: выражения. Реализация выражений — это BindingExpression и DynamicResourceExpression, которые обеспечивают работу привязки данных и динамических ссылок на ресурсы соответственно. В сущности, выражения используются как расширения источников значений для Dependency Property. Значения выражений при этом всё-равно кладутся по месту.
Согласен. Биндинг, как часть базовой системы, имеющий свое собственное API, вполне может быть вшит в DependencyObject изнутри.
Только я одного не пойму: вот имеем мы в WPF какое-либо свойство, например, с типом int. Для установки значения, базовая система, т.е. DependencyObject, нам предоставляет только метод SetValue. Как ты говоришь WPF записывает значение с признаком (с флагом, откуда это значение взято). Значит WPF не может записать при помощи SetValue просто int, т.к. надо куда то сохранить и флаг. Куда флаг то сохраняется? Я конечно понимаю, что можно обернуть наш int в некую структуру, в которой будет два поля: наш int и флаг, и записать эту структуру при помощи SetValue. Тока, тогда (не говоря уже о том, что система не даст этого сделать, т.к. тип значения не совпадает с метаданными) GetValue вернет потом совсем не int...
Т.о. вопрос: куда и каким API базовой системы WPF сохраняет флаг?
Здравствуйте, stalcer, Вы писали:
MM>>Почему вообще всплыла эта тема с экономией памяти? S>Дык так везде написано, в том числе и в их же доках. Я понимаю, что это не единственное для чего их придумали.
Подразумевают, что в объекте присутствуют данные для тех свойств, которые действительно использовали. В FrameworkElement несколько десятков свойств, но фактически память для них будет выделяться только для тех, которым присвоят отличные от default значения. На объектах, у которых два-три свойства, особой экономии, естественно, не выйдет.
MM>>Dependency Property придумали не для экономии, а как некоторый селектор эффективного значения из разных источников. S>Вот тут меня и клинит. Потому что, если это "некоторый селектор эффективного значения из разных источников", то почему же в DependencyObject нет методов с помощью которых можно было бы указать эти "разные источники" для данного объекта.
Потому что "список источников" определен в WPF. Никто не обещал, что DependencyObject предоставляет безграничную свободу. Есть дюжина возможных источников, у каждого есть свой приоритет. Этим и предлагается пользоваться.
S>Согласен. Биндинг, как часть базовой системы, имеющий свое собственное API, вполне может быть вшит в DependencyObject изнутри.
Строго говоря, Binding не вшит в DependencyObject. Привязка данных реализована в PresentationFramework, как подвид выражений. Вот эти самые выражения и поддерживает DependencyObject.
S>Только я одного не пойму: вот имеем мы в WPF какое-либо свойство, например, с типом int. Для установки значения, базовая система, т.е. DependencyObject, нам предоставляет только метод SetValue. Как ты говоришь WPF записывает значение с признаком (с флагом, откуда это значение взято). Значит WPF не может записать при помощи SetValue просто int, т.к. надо куда то сохранить и флаг. Куда флаг то сохраняется? Я конечно понимаю, что можно обернуть наш int в некую структуру, в которой будет два поля: наш int и флаг, и записать эту структуру при помощи SetValue. Тока, тогда (не говоря уже о том, что система не даст этого сделать, т.к. тип значения не совпадает с метаданными) GetValue вернет потом совсем не int... S>Т.о. вопрос: куда и каким API базовой системы WPF сохраняет флаг?
Внутри себя DependencyObject использует такие структуры, как EntryIndex и EffectiveValueEntry. EntryIndex является ключом хэш-таблицы, а EffectiveValueEntry — значением. EffectiveValueEntry хранит в себе значение свойства и различные флаги, в том числе, если не ошибаюсь, при необходимости и ссылку на выражение. Соответственно, GetValue извлекает значение из поля EffectiveValueEntry.
Здравствуйте, MxMsk, Вы писали:
MM>Внутри себя DependencyObject использует такие структуры, как EntryIndex и EffectiveValueEntry. EntryIndex является ключом хэш-таблицы, а EffectiveValueEntry — значением. EffectiveValueEntry хранит в себе значение свойства и различные флаги, в том числе, если не ошибаюсь, при необходимости и ссылку на выражение. Соответственно, GetValue извлекает значение из поля EffectiveValueEntry.
Допускаю, что так оно и есть. Вопрос то не в этом. Еще раз: есть две подсистемы:
1) DependencyObject
2) WPF
Первая от второй не зависит. Так как (ты сам это подметил) первая находится в отдельной сборке. Следовательно, чтобы сохранить что-то в хэш-таблице, которая находится в первой подсистеме, вторая подсистема должна использовать какое-либо публичное API первой подсистемы.
Вопрос: При помощи какого API первой подсистемы вторая подсистема (т.е. WPF) кладет флаг (признак) того, что значение взято из, например, стиля?
Здравствуйте, stalcer, Вы писали:
S>Вопрос: При помощи какого API первой подсистемы вторая подсистема (т.е. WPF) кладет флаг (признак) того, что значение взято из, например, стиля?
Аааааа Ну, для этого используется сочетание области видимости internal с атрибутом InternalsVisibleTo. Засчет этого PresentationFramework "видит" в WindowsBase больше того, что видно нам. Но это внутренние механизмы — не стоит уделять им так много внимания.
Здравствуйте, MxMsk, Вы писали:
MM>Аааааа Ну, для этого используется сочетание области видимости internal с атрибутом InternalsVisibleTo. Засчет этого PresentationFramework "видит" в WindowsBase больше того, что видно нам. Но это внутренние механизмы — не стоит уделять им так много внимания.