Есть ли у людей какие-либо рекомендации, когда достаточно простого свойства .NET, которое запускает INotifyPropertyChanged.PropertyChanged
, достаточно в модели представления? Затем, когда вы хотите перейти к полномасштабному имуществу зависимостей? Или DP, предназначенные в первую очередь для просмотра?
Когда использовать свойство зависимости WPF от INotifyPropertyChanged
Ответ 1
Существует несколько подходов:
1. Свойство зависимостей
В то время как вы используете свойство зависимости, он имеет наибольший смысл в классах элементов, которые имеют визуальный внешний вид (UIElement
s).
Плюсы:
- WPF делает для вас логический материал.
- Некоторые механизмы, такие как анимация, используют только свойство зависимостей
- Стиль "Подгонка стиля"
Минусы:
- Вам нужно получить форму
DependencyObject
- Немного неудобно для простых вещей
Пример:
public static class StoryBoardHelper
{
public static DependencyObject GetTarget(Timeline timeline)
{
if (timeline == null)
throw new ArgumentNullException("timeline");
return timeline.GetValue(TargetProperty) as DependencyObject;
}
public static void SetTarget(Timeline timeline, DependencyObject value)
{
if (timeline == null)
throw new ArgumentNullException("timeline");
timeline.SetValue(TargetProperty, value);
}
public static readonly DependencyProperty TargetProperty =
DependencyProperty.RegisterAttached(
"Target",
typeof(DependencyObject),
typeof(Timeline),
new PropertyMetadata(null, OnTargetPropertyChanged));
private static void OnTargetPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Storyboard.SetTarget(d as Timeline, e.NewValue as DependencyObject);
}
}
2. System.ComponentModel.INotifyPropertyChanged
Обычно, создавая объект данных, вы используете этот подход. Это простое и аккуратное решение для Data-подобных материалов.
Плюсы и минусы - дополняющие 1. Вам нужно реализовать только одно событие (PropertyChanged).
Пример:
public class Student : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null)
PropertyChanged(this, e);
}
}
private string name;
public string Name;
{
get { return name; }
set {
name = value;
OnPropertyChanged(new PropertyChangedEventArgs("Name"));
}
}
3.PropertyName Измененный
Поднятие события для каждого свойства с указанным именем (f.e. NameChanged). Событие должно иметь это имя, и вы должны обрабатывать/поднимать их. Аналогичный подход как 2.
4. Получить привязку
Используя FrameworkElement.GetBindingExpression()
, вы можете получить объект BindingExpression
и вызовите BindingExpression.UpdateTarget()
для обновления.
Первый и второй наиболее вероятны в зависимости от вашей цели.
В целом, это Visual vs Data.
Ответ 2
Насколько мне известно, DependencyProperty
требуется только тогда, когда вам нужно
- Наследование PropertyValue
- вам нужно разрешить настройку свойства в установках стилей.
- Использовать анимацию для свойства
и т.д..
Эти функции не будут доступны с нормальными свойствами.
Ответ 3
DependencyProperty
требуется, если вы хотите разрешить привязку к свойству. Обычно это для пользовательских UIElement
, которые вы создаете. Вы хотите, чтобы люди могли привязывать данные к вашим UIElement
s.
<local:MyUIElement MyProperty={Binding Path=SomethingToBindTo} />
Для этого требуется, чтобы MyProperty являлся свойством зависимостей
Ответ 4
Основная проблема, с которой я сталкиваюсь с INotifyPropertyChanged
, заключается в том, что если viewmodel сложна, содержащая много вложенных типов, кажется, что вы должны пузырить событие PropertyChanged
через иерархию.
Ответ 5
В качестве других ответов уже достаточно сказано о том, когда создавать свойство зависимостей. то есть.
- Наследование PropertyValue
- вам нужно использовать привязку для свойства
- Использовать анимацию для свойства
Еще одна перспектива/вопрос по этому вопросу: "В приложении WPF имеет смысл создавать свойства зависимостей в элементе управления, потому что они могут измениться во время взаимодействия с пользователем, например, высота, ширина, текст, содержание, фон и т.д. но как насчет других классов, таких как классы поведения (классы без интерфейса). У свойств в этих классах должно быть свойство зависимостей?
Я не буду говорить об абсолютном или акцентирующемся на некоторых правилах здесь, но вы должны создать свои свойства как DP. Поскольку с точки зрения дизайна, если свойство является DP, он всегда использует форму WPF для использования /bind.i.e.
- Поскольку DP намного более быстрый/естественный в отражении изменений по сравнению с обычным свойством CLR.
- У DP есть механизм валидации для проверки присвоенного значения и структуры по умолчанию, чтобы вернуть значение.
- У DP есть обратный вызов значения Coerce для ограничения пределов свойства.
- У DP есть метаданные, связанные с ним, в отличие от свойства CLR.
С точки зрения практики я видел, как люди совершают много ошибок во вложенных привязках, а затем поднимая изменения, подобные ошибки не происходят с причиной его создания и совместимости с самим повышением самих изменений. Поэтому с небольшим дополнительным синтаксисом вы придаете вашему приложению гибкость/производительность/простоту. Поэтому идите туда, где это возможно.
Все еще не может быть уверен в классах ViewModel/других вспомогательных классах. будет обновлять ответ, если в будущем будут найдены убедительные причины.