Ответ заключается в самом названии, хотя слово «зависимость» настолько чревато смыслом в разработке программного обеспечения, что не совсем понятно, что это значит.
Свойство зависимости - это свойство одного объекта, чьезначение зависит от некоторых других объектов.Так, например:
Значение свойства FontFamily
TextBox
может (и обычно так) зависит от свойства FontFamily
его контейнера.При изменении свойства контейнера значение TextBox
изменится.
Значение свойства Text
TextBox
может зависеть от привязанного источника данных,При изменении значения связанного свойства значение свойства Text
изменяется.
Значение свойства Opacity
для Label
может зависеть от раскадровки анимациив обычном сценарии, в котором вы настроили элемент пользовательского интерфейса для постепенного или постепенного исчезновения в ответ на какое-либо событие.
Значение всех видов свойств любого элемента пользовательского интерфейса можетзависит от стиля, который вы к ним применили.
Основная концепция зависимости заключается в том, что зависимая вещь должна получать значение свойства от той, от которой она зависит.Вот почему свойство зависимости реализовано в виде свойства CLR, метод получения которого вызывает метод.
Когда TextBox
или объекту, который его отображает, необходимо знать, что это за FontFamily
, FontFamily
getter вызывает метод GetValue
.Этот метод находит значение из контейнера, или анимации, или привязки, или чего-то еще.
В этом методе много сложностей.Например, если значение унаследовано, оно работает аналогично тому, как WPF находит стили в словаре ресурсов: он ищет в локальном словаре значение, а если нет записи, он ищет в словаре своего родителя, итак до тех пор, пока он не найдет значение или не достигнет вершины иерархии, в этом случае он использует значение по умолчанию.
Если вы посмотрите на реализацию свойств зависимостей, это то, что вы найдете.У объекта зависимости есть словарь, который может содержать или не содержать запись для данного свойства.Метод GetValue
получает значения из этого словаря (то есть, как объекты со свойствами зависимости могут иметь локальные значения, которые переопределяют то, от чего они наследуются), и если он не находит значение, он использует метаинформацию о свойстве длявыясните, где он должен выглядеть.
Поскольку эта метаинформация одинакова для каждого объекта в классе (т. е. TextBox.Text
работает одинаково для каждого TextBox
), словарь, в котором он хранится, является статическим свойствомкласса.
Поэтому, когда вы видите код, подобный следующему:
static Button()
{
// Register the property
Button.IsDefaultProperty =
DependencyProperty.Register("IsDefault",
typeof(bool), typeof(Button),
new FrameworkPropertyMetadata(false,
new PropertyChangedCallback(OnIsDefaultChanged)));
}
, то происходит то, что метаинформация, определяющая свойство IsDefault
для всех объектов Button
, добавляется вэтот словарь.И когда вы видите это:
public bool IsDefault
{
get { return (bool)GetValue(Button.IsDefaultProperty); }
set { SetValue(Button.IsDefaultProperty, value); }
}
то, что вы видите, - это метод getter, который ищет значение свойства (из локального словаря, родительского объекта или чего-либо еще) на основе этой метаинформации.
Помните, как я сказал, что первое место, которое ищет геттер, чтобы найти значение свойства, находится в локальном словаре объекта?Метод SetValue
в установщике - это то, как эта запись добавляется в словарь (если он когда-либо вызывается, то будет, только если вы переопределите зависимость, явно установив свойство, то есть говоря: «Я хочу это TextBox
»для отображения текста в Consolas
независимо от того, что используют другие элементы управления в окне. ").
Чрезвычайно значительное преимущество, которое мы получаем от такого рода очевидно сложной системы, состоит в том, что свойства зависимостей от объектов только потребляют память, если они установлены. Если я создаю 10 000 TextBox
элементов управления и добавляю их к Window
, ни один из них на самом деле не содержит ссылку на FontFamily
объект. Это 10000 ссылок на объекты, для которых я не выделяю память, и что сборщик мусора не проверяет. На самом деле, если TextBox
имеет 100 свойств зависимостей (и он имеет примерно), то всякий раз, когда вы создаете TextBox
, это 100 вспомогательных полей, для которых вы не выделяете память. Свойства зависимостей потребляют память только в том случае, если вы их явно указали. Поскольку подавляющее большинство свойств объектов пользовательского интерфейса никогда не устанавливается явно, это фантастическая экономия.