Свойство зависимости в XAML
  1. В WPF вводится новый тип свойства, называемый свойством зависимости Dependency Property. 
  2. Это свойство поддерживается системой свойств WPF. 
  3. Оно используется для анимации, разрешая использование стилей, автоматическую привязку данных и многое другое. 
  4. Оно использует несколько поставщиков для определения своего значения в любой момент времени.
  5. Самой главной функцией свойства зависимости является ее встроенная возможность обеспечивать УВЕДОМЛЕНИЕ ОБ ИЗМЕНЕНИИ. 
  6. Основным стимулом к добавлению свойства зависимости явилось желание обеспечить богатые функциональные возможности прямо в декларативном языке разметки. 
  7. Цель свойства зависимости заключается в поиске значения свойства на основе значений других входных данных.

Другими входными данными могут быть:

  • темы стилей; 
  • предпочтения пользователей 
  • своевременное определение свойства; 
  • анимация и т. д.

Пример

Имеется 96 публичных свойств объекта Button. Свойства можно легко задать в XAML без использования процедурного кода. Но без добавления свойства зависимости, чтобы добиться желаемого результата даже для простого задания свойств, пришлось бы писать дополнительный код.

Цель свойств зависимости — предоставить способ рассчитывать значение свойства на основе значений других входных данных.

Использование свойством объекта свойства зависимости обеспечивает поддержку привязки данных, анимации, значения по умолчанию, стилей и т. д.

Свойство зависимости поддерживает использование нескольких поставщиков.  Для получения окончательного значения свойства зависимости в WPF должно быть выполнено пять действий.

Шаг 1.  Определение базового значения

Базовое значение свойства зависимости устанавливается следующими поставщиками Они перечислены в порядке своего приоритета (от наивысшего к самому низкому).

  1. Локальное значение 
  2. Триггеры стилей 
  3. Триггеры шаблонов 
  4. Триггеры методов задания 
  5. Триггеры стилей тем
  6. Методы задания стилей тем
  7. Наследование значения свойства 
  8. Значение по умолчанию.

Шаг 2.  Оценка

Если результатом шага 1 является выражение, то оно окончательно вычисляется на этом этапе.  WPF преобразует выражение в конкретное значение.

Шаг 3. Применение анимации

Любые выполняемые анимации могут либо заменить, либо изменить значение свойства зависимости.

Шаг 4. Ограничение

WPF получает окончательное значение свойства и передает его делегату CorecevalueCallBack. Это позволяет проверить, не выполняется ли какая-либо настраиваемая логика задания значения для свойства зависимости. Этот обратный вызов отвечает а возвращение нового значения, зависящего от настраиваемой логики.

Шаг 5. Проверка

Теперь конечное значение передается делегату ValidateValueCallBack, который проверяет, является ли значение допустимым или нет.

Пример использования свойства зависимости

Пусть требуется выполнить следующие действия.

  1. Изменить цвет текста кнопки при наведении на нее указателя мыши. 
  2. Когда указатель мыши оказывается над кнопкой, цвет текста должен измениться на синий (BLUE). 
  3. Когда указатель мыши перемещается за пределы кнопки, цвет текста меняется обратно на черный (BLACK).

Без специальной возможности УВЕДОМЛЕНИЯ ОБ ИЗМЕНЕНИИ, обеспечиваемой свойством зависимости.


Шаг 1.
Создайте тег XAML для кнопки с двумя событиями, как показано ниже

<Window x:Class="WpfApplication2.Window1"
   xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
 
 
   Title="Window1" Loaded="Window_Loaded"  Height="300" Width="300">
  <Grid>
  <Button MouseEnter="Button_MouseEnter" MouseLeave="Button_MouseLeave"  Height="100" Width="100"> Testing Button </Button>
  </Grid>
</Window>

Здесь событиями являются Button_MouseEnter  и  Button_MouseLeave.

Шаг 2.
Теперь нужно написать фоновый код, обрабатывающий эти события. Код будет похож на следующий

private void Button_MouseEnter(object sender, MouseEventArgs e)
  {
  Button b = sender as Button;
  if (b != null)
  {
  b.Foreground = Brushes.Blue;
  }
  }
  private void Button_MouseLeave(object sender, MouseEventArgs e)
  {
  Button b = sender as Button;
  if (b != null)
  {
  b.Background = Brushes.Black;
  }
  }

Теперь для решения описанной задачи можно легко использовать XAML со свойством зависимости.

<Window x:Class="WpfApplication2.Window1"
   xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" 
  Title="Window1" Loaded="Window_Loaded"  Height="300" Width="300">
  <Grid>
  <Button  Height="100" MinWidth="75" Margin="10">
  <Button.Style>
  <Style TargetType="{x:Type Button}">
  <Style.Triggers>
  <Trigger Property="IsMouseOver" Value="True">
  <Setter Property="Foreground" Value="Blue"/>
  </Trigger>
  </Style.Triggers>
  </Style>
  </Button.Style>
  OK
  </Button>
  </Grid>
</Window>