AttachedProperty
Это подвид DependencyProperty, которые объявляются в одном классе, а значения устанавливаются для экземпляров другого класса. Один из самых распространенных примеров – Grid.Row и Grid.Column, которые устанавливаются для контролей, вложенных в грид.
Особенности
- Класс, в котором объявлено AttachedProperty не обязательно должен наследоваться от DependencyObject.
- Классы, для экземпляров которых устанавливается значение AttachedProperty, должны быть унаследованы от DependencyObject.
Создание AttachedProperty
Создаем класс, в нем пишем propa и два раза нажимаем tab. Студия сгенерирует заготовку, в ней меняем имя свойства, его тип и значение по умолчанию.
public static class BackgroundManager { public static bool GetNeedGrayBackground(DependencyObject obj) { return (bool)obj.GetValue(NeedGrayBackgroundProperty); } public static void SetNeedGrayBackground(DependencyObject obj, bool value) { obj.SetValue(NeedGrayBackgroundProperty, value); } public static readonly DependencyProperty NeedGrayBackgroundProperty = DependencyProperty.RegisterAttached("NeedGrayBackground", typeof(bool), typeof(BackgroundManager), new PropertyMetadata(false)); }
Видим два отличия от DependencyProperty:
- Свойство регистрируется с помощью метода RegisterAttached, а не Register.
- Враппер генерируется в виде парных методов, а не в виде свойства.
Враппер так же не вызывается при установке значения в XAML, он нужен для доступа к свойству из кода.
По аналогии с DependencyProperty добавим обработчик изменения значения:
public static readonly DependencyProperty NeedGrayBackgroundProperty = DependencyProperty.RegisterAttached("NeedGrayBackground", typeof(bool), typeof(BackgroundManager), new PropertyMetadata(false, NeedGrayBackground)); public static void NeedGrayBackground(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (!(bool)e.NewValue) return; var control = d as Control; if (control != null) control.Background = Brushes.Gray; }
Если новое значение свойства true и переданный объект является контролом – устанавливаем его Background в серый цвет.
Теперь соберем окно для проверки:
< Window x:Class="WpfApplication36.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApplication36" Title="MainWindow" Width="525" Height="350"> < StackPanel> < Label local:BackgroundManager.NeedGrayBackground="True">Button1< /Label> < Label>Button2< /Label> < Label>Button3< /Label> < /StackPanel> < /Window>
Запускаем
У обработчиков изменения значения DependencyProperty есть одна особенность – они не вызываются, если новое значение свойства совпадает со старым.