Как повысить свойства Измененные события в зависимости от свойства?

Хорошо, поэтому у меня есть этот элемент управления с двумя свойствами. Один из них – DependencyProperty, другой – «псевдоним» первого. То, что мне нужно, – это поднять событие PropertyChanged для второго (псевдоним), когда первый изменяется.

ПРИМЕЧАНИЕ . Я использую DependencyObjects, а не INotifyPropertyChanged (попробовал это, не работал, потому что мой элемент управления является подclassифицированным ListView)

что-то вроде этого…..

protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) { base.OnPropertyChanged(e); if (e.Property == MyFirstProperty) { RaiseAnEvent( MySecondProperty ); /// what is the code that would go here? } } 

Если бы я использовал INotify, я мог бы это сделать …

 public string SecondProperty { get { return this.m_IconPath; } } public string IconPath { get { return this.m_IconPath; } set { if (this.m_IconPath != value) { this.m_IconPath = value; this.SendPropertyChanged("IconPath"); this.SendPropertyChanged("SecondProperty"); } } } 

где я могу поднимать события PropertyChanged по нескольким свойствам из одного сеттера. Мне нужно иметь возможность делать то же самое, только используя DependencyProperties.

  1. INotifyPropertyChanged в свой class.

  2. Укажите обратный вызов в метаданных свойств при регистрации свойства зависимости.

  3. В обратном вызове поднимите событие PropertyChanged.

Добавление обратного вызова:

 public static DependencyProperty FirstProperty = DependencyProperty.Register( "First", typeof(string), typeof(MyType), new FrameworkPropertyMetadata( false, new PropertyChangedCallback(OnFirstPropertyChanged))); 

Привлечение PropertyChanged в обратном вызове:

 private static void OnFirstPropertyChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e) { PropertyChangedEventHandler h = PropertyChanged; if (h != null) { h(sender, new PropertyChangedEventArgs("Second")); } } 

Я столкнулся с аналогичной проблемой, когда у меня есть свойство зависимостей, которое я хотел, чтобы class прослушивал события изменения, чтобы захватить связанные данные из службы.

 public static readonly DependencyProperty CustomerProperty = DependencyProperty.Register("Customer", typeof(Customer), typeof(CustomerDetailView), new PropertyMetadata(OnCustomerChangedCallBack)); public Customer Customer { get { return (Customer)GetValue(CustomerProperty); } set { SetValue(CustomerProperty, value); } } private static void OnCustomerChangedCallBack( DependencyObject sender, DependencyPropertyChangedEventArgs e) { CustomerDetailView c = sender as CustomerDetailView; if (c != null) { c.OnCustomerChanged(); } } protected virtual void OnCustomerChanged() { // Grab related data. // Raises INotifyPropertyChanged.PropertyChanged OnPropertyChanged("Customer"); } 

Я думаю, что ОП задает неправильный вопрос. В приведенном ниже коде будет показано, что для достижения желаемого результата вручную не нужно вручную создавать свойство PropertyChanged EVENT из свойства зависимостей. Способ сделать это – обработать PropertyChanged CALLBACK на свойстве зависимостей и установить значения для других свойств зависимостей там. Ниже приведен рабочий пример. В приведенном ниже коде MyControl имеет два свойства зависимостей – ActiveTabInt и ActiveTabString. Когда пользователь нажимает кнопку на хосте (MainWindow), изменяется ActiveTabString. Свойство PropertyChanged CALLBACK для свойства зависимостей устанавливает значение ActiveTabInt. Событие PropertyChanged EVENT не вручную создано MyControl.

MainWindow.xaml.cs

 ///  /// Interaction logic for MainWindow.xaml ///  public partial class MainWindow : Window, INotifyPropertyChanged { public MainWindow() { InitializeComponent(); DataContext = this; ActiveTabString = "zero"; } private string _ActiveTabString; public string ActiveTabString { get { return _ActiveTabString; } set { if (_ActiveTabString != value) { _ActiveTabString = value; RaisePropertyChanged("ActiveTabString"); } } } private int _ActiveTabInt; public int ActiveTabInt { get { return _ActiveTabInt; } set { if (_ActiveTabInt != value) { _ActiveTabInt = value; RaisePropertyChanged("ActiveTabInt"); } } } #region INotifyPropertyChanged implementation public event PropertyChangedEventHandler PropertyChanged; public void RaisePropertyChanged(string propertyName) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } #endregion private void Button_Click(object sender, RoutedEventArgs e) { ActiveTabString = (ActiveTabString == "zero") ? "one" : "zero"; } } public class MyControl : Control { public static List Indexmap = new List(new string[] { "zero", "one" }); public string ActiveTabString { get { return (string)GetValue(ActiveTabStringProperty); } set { SetValue(ActiveTabStringProperty, value); } } public static readonly DependencyProperty ActiveTabStringProperty = DependencyProperty.Register( "ActiveTabString", typeof(string), typeof(MyControl), new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, ActiveTabStringChanged)); public int ActiveTabInt { get { return (int)GetValue(ActiveTabIntProperty); } set { SetValue(ActiveTabIntProperty, value); } } public static readonly DependencyProperty ActiveTabIntProperty = DependencyProperty.Register( "ActiveTabInt", typeof(Int32), typeof(MyControl), new FrameworkPropertyMetadata( new Int32(), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); static MyControl() { DefaultStyleKeyProperty.OverrideMetadata(typeof(MyControl), new FrameworkPropertyMetadata(typeof(MyControl))); } public override void OnApplyTemplate() { base.OnApplyTemplate(); } private static void ActiveTabStringChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { MyControl thiscontrol = sender as MyControl; if (Indexmap[thiscontrol.ActiveTabInt] != thiscontrol.ActiveTabString) thiscontrol.ActiveTabInt = Indexmap.IndexOf(e.NewValue.ToString()); } } 

MainWindow.xaml

      

App.xaml

  

Я согласен с Сэмом и Xaser и на самом деле это немного дальше. Я не думаю, что вы должны внедрять интерфейс INotifyPropertyChanged в UserControl вообще … элемент управления уже является DependencyObject и поэтому уже содержит уведомления. Добавление INotifyPropertyChanged в DependencyObject избыточно и «неприятно» для меня.

То, что я сделал, реализует оба свойства как DependencyProperties, как предлагает Сэм, но тогда просто свойство PropertyChangedCallback из свойства «first» dependency изменило значение свойства «второй» зависимости. Поскольку оба являются свойствами зависимостей, оба автоматически повышают уведомления об изменениях любым заинтересованным абонентам (например, привязка данных и т. Д.),

В этом случае свойство зависимостей A представляет собой строку InviteText, которая вызывает изменение свойства зависимости B, свойство Видимость с именем ShowInvite. Это будет распространенный случай использования, если у вас есть текст, который вы хотите полностью скрыть в элементе управления через привязку данных.

  public string InviteText { get { return (string)GetValue(InviteTextProperty); } set { SetValue(InviteTextProperty, value); } } public static readonly DependencyProperty InviteTextProperty = DependencyProperty.Register("InviteText", typeof(string), typeof(InvitePrompt), new UIPropertyMetadata(String.Empty, OnInviteTextChanged)); private static void OnInviteTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { InvitePrompt prompt = d as InvitePrompt; if (prompt != null) { string text = e.NewValue as String; prompt.ShowInvite = String.IsNullOrWhiteSpace(text) ? Visibility.Collapsed : Visibility.Visible; } } public Visibility ShowInvite { get { return (Visibility)GetValue(ShowInviteProperty); } set { SetValue(ShowInviteProperty, value); } } public static readonly DependencyProperty ShowInviteProperty = DependencyProperty.Register("ShowInvite", typeof(Visibility), typeof(InvitePrompt), new PropertyMetadata(Visibility.Collapsed)); 

Примечание. Я не включаю подпись или конструктор UserControl здесь, потому что в них нет ничего особенного; они вообще не нуждаются в подclassе из INotifyPropertyChanged.

Я сомневаюсь в логике создания события PropertyChanged во втором свойстве, когда это первое свойство, которое меняется. Если второе значение свойства изменяется, то событие PropertyChanged может быть поднято там.

Во всяком случае, ответ на ваш вопрос заключается в том, что вы должны внедрить INotifyPropertyChange. Этот интерфейс содержит событие PropertyChanged. Реализация INotifyPropertyChanged позволяет другому коду знать, что class имеет событие PropertyChanged, поэтому код может подключить обработчик. После реализации INotifyPropertyChange код, который входит в инструкцию if вашего OnPropertyChanged:

 if (PropertyChanged != null) PropertyChanged(new PropertyChangedEventArgs("MySecondProperty")); 
  • ComboBox.SelectedValue не обновляется из источника привязки
  • В .NET 4.0 привязка OneWayToSource
  • Привязка списка в @RequestParam
  • Как связать List с элементом управления DataGridView?
  • Ранняя и поздняя привязка
  • Конфликты Datacontext
  • Почему обновление привязки не реализует INotifyPropertyChanged?
  • Как форматировать столбцы DateTime в DataGridView?
  • Связывание со статическим свойством
  • Ошибка привязки элемента ElementName
  • Пользовательское связующее устройство DateTime в Asp.net MVC
  • Давайте будем гением компьютера.