Обратный вызов, когда свойство зависимостей получает изменение xaml
Когда я устанавливаю значение IsClosed
во время выполнения, OnIsClosedChanged()
называется штрафом. Однако конструктор устанавливает значение свойства, но не вызывает OnIsClosedChanged()
.
public static DependencyProperty IsClosedProperty = DependencyProperty.Register("IsClosed", typeof(bool), typeof(GroupBox), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender)); public bool IsClosed { get { return (bool)this.GetValue(IsClosedProperty); } set { if ((bool)this.GetValue(IsClosedProperty) == value) return; this.SetValue(IsClosedProperty, value); OnIsClosedChanged(); } } private void OnIsClosedChanged() { _rowDefContent.Height = new GridLength((IsClosed ? 0 : 1), GridUnitType.Star); }
Очевидно, что IsClosed
не изменяется конструктором, и только IsClosedProperty
получает изменение xaml.
Мой вопрос: как я могу запустить IsClosed
после того, как значение было изменено в Designer. Или, по крайней мере, добавить некоторую логику к изменениям, не связанным с исполнением.
- Как настроить log4j с файлом свойств
- Передача свойств по ссылке в C #
- Установить свойство объекта с помощью отражения
- В чем разница между иварами и свойствами в Objective-C
- Действительное использование аксессуаров в методах init и dealloc?
- Внешние свойства контекста приложения приложения?
- Настройка Tomcat для использования файла свойств для загрузки информации о соединении DB
- Атрибут .NET DefaultValue
- Ошибка в classе Swift: свойство не инициализировано при вызове super.init
- Являются ли функции get и set популярными у программистов на C ++?
- В Objective-C на iOS, какова разница между «self.foo» и «foo» при использовании синтезированных геттеров?
- Как использовать файлы свойств Java?
- Как заполнить HashMap из файла свойств java с помощью Spring @Value
Вам нужно будет зарегистрировать PropertyChangedCallback с метаданными свойств.
Причина в том, что свойства зависимостей, установленные в XAML или привязками или каким-либо другим источником, не вызывают оболочку CLR (метод setter). Причина объясняется в статье свойств XAML по загрузке и зависимостям в MSDN:
По соображениям реализации вычислительно дешевле идентифицировать свойство как свойство зависимостей и обращаться к методу SetValue системы свойств, чтобы установить его, а не использовать оболочку свойств и ее сеттер.
…
Поскольку текущая реализация WPF поведения процессора XAML для параметра свойства полностью обходит обертки, вы не должны вводить какую-либо дополнительную логику в определения набора обертки для вашего пользовательского свойства зависимостей. Если вы поместите такую логику в определение набора, тогда логика не будет выполняться, если свойство задано в XAML, а не в коде.
Ваш код должен выглядеть так:
public static readonly DependencyProperty IsClosedProperty = DependencyProperty.Register( "IsClosed", typeof(bool), typeof(GroupBox), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender, (o, e) => ((GroupBox)o).OnIsClosedChanged())); public bool IsClosed { get { return (bool)GetValue(IsClosedProperty); } set { SetValue(IsClosedProperty, value); } } private void OnIsClosedChanged() { _rowDefContent.Height = new GridLength((IsClosed ? 0 : 1), GridUnitType.Star); }
Теперь я нашел ответ. ValidateValueCallback действительно близок! (как указал Алекс К). Но это статический метод, и я не получаю никакой ссылки на экземпляр, который был изменен. Ключом является использование PropertyChangedCallback в FrameworkPropertyMetadata, который также является аргументом, переданным методу Property.Register.
Видеть:
public static DependencyProperty IsClosedProperty = DependencyProperty.Register("IsClosed", typeof(bool), typeof(GroupBox), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(OnIsClosedChangedPCC))); public bool IsClosed { get { return (bool)this.GetValue(IsClosedProperty); } set { this.SetValue(IsClosedProperty, value); OnIsClosedChanged(); } } private static void OnIsClosedChangedPCC(DependencyObject d, DependencyPropertyChangedEventArgs e) { GroupBox current = (GroupBox)d; current.IsClosed = current.IsClosed; } private void OnIsClosedChanged() { _rowDefContent.Height = new GridLength((IsClosed ? 0 : 1), GridUnitType.Star); }
Теперь он снова устанавливает IsClosedValue
который запускает OnIsClosedChanged
.
Спасибо за помощь ребята!