The associated property set did not receive

I have a problem with the following scenario (shortening the code for short). Basically, the Setter of my User Control property is not called when the dependency property is set, and I need to get around this.

I have the following code in my View.xaml

<Filter:Filter x:Name="ProductFilter" PrimaryItemSource="{Binding CarrierProducts}" /> 

In View.xaml.cs

  public ProductPricing() { InitializeComponent(); ViewModel.Filter.ProductPricing vm = new ViewModel.Filter.ProductPricing(); this.DataContext = vm; } 

In my ViewModel, I set the property

  public ObservableCollection<Model.FilterItem> _carrierProducts; public ObservableCollection<Model.FilterItem> CarrierProducts { get { return _carrierProducts; } set { if (_carrierProducts != value) { _carrierProducts = value; RaisePropertyChanged("CarrierProducts"); } } } 

Finally, the user filter control is defined as follows.

  public static readonly DependencyProperty PrimaryItemSourceProperty = DependencyProperty.Register("PrimaryItemSource", typeof(ObservableCollection<Model.FilterItem>), typeof(Filter), new PropertyMetadata(null)); public ObservableCollection<Model.FilterItem> PrimaryItemSource { get { return (ObservableCollection<Model.FilterItem>)GetValue(PrimaryItemSourceProperty); } set { SetValue(PrimaryItemSourceProperty, value); ComboBox combo = _filters.ElementAt(0); FilterSourceChange(combo, value); } } 

For some reason, the PrimaryItemSource property is set, but Setter is not called. Should I add a PropertyChange event to the PropertyMetadata object to handle this, as this seems like a lot of code for something simple.

+4
source share
3 answers

Yes, always use a callback if you need additional logic for the installer. This is required in Silverlight and WPF.

To my knowledge, Setter will only be called when using code. When you bind, everything happens using the DependencyProperty infrastructure.

You should also wrap your ComboBox combo = ... code in this.Dispatcher.BeginInvoke(() => ... ); , because it ensures that the visual tree is initialized.

+3
source

This is how the Dependency property should be written, which requires additional code to run on the set: -

  public ObservableCollection<Model.FilterItem> PrimaryItemSource { get { return (ObservableCollection<Model.FilterItem>)GetValue(PrimaryItemSourceProperty); } set { SetValue(PrimaryItemSourceProperty , value); } } public static readonly DependencyProperty PrimaryItemSourceProperty = DependencyProperty.Register( "PrimaryItemSource", typeof(ObservableCollection<Model.FilterItem>), typeof(Filter), new PropertyMetadata(null, OnPrimaryItemSourceChanged)); private static void OnPrimaryItemSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Filter filter = (Filter)d; var oldValue = (ObservableCollection<Model.FilterItem>)e.OldValue; var newValue = (ObservableCollection<Model.FilterItem>)e.NewValue; filter.OnPrimaryItemSourceChanged(oldValue, newValue); } protected virtual void OnPrimaryItemSourceChanged( ObservableCollection<Model.FilterItem> oldValue, ObservableCollection<Model.FilterItem> newValue) { ComboBox combo = _filters.ElementAt(0); FilterSourceChange(combo, newValue); } 

You use the place of the DependencyPropertyChanged static handler in the class, which resets the dependency object to the correct type, and then calls the instance method to alert the instance of the change.

This change handler will be called whenever the dependency dependency property is changed: by calling SetValue in the Set property or by binding or in any other way.

+5
source

The last parameter of the DependencyProperty.Register () method accepts the PropertyMetaData property in which you pass the null value. One of the constructor overloads takes the PropertyChangedCallback property. Use this overload to define a callback function that will be called when your property changes.

 static void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { Filter filter = d as Filter; ComboBox combo = filter._filters.ElementAt(0); filter.FilterSourceChange(combo, filter.PrimaryItemSource); } 
+1
source

Source: https://habr.com/ru/post/1300884/


All Articles