Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bound Property Setter not getting Called

Tags:

silverlight

I have a problem with the following scenario (code cut for brevity). Basically the Setter of my User Control Property isn't being 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 the View.xaml.cs

    public ProductPricing()
    {
        InitializeComponent();

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

In my ViewModel I expose a property

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

Finally the Filter User control is defined like so.

   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 the Setter doesn't get called. Do I have to add a PropertyChange event to the PropertyMetadata object to handle this as that seems like a lot of code for something simple.

like image 699
James Hughes Avatar asked Jan 22 '23 14:01

James Hughes


1 Answers

This is how a Dependency property that requires additional code to be run on set should be written:-

 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 place a static DependencyPropertyChanged handler in the class that will cast down the dependency object to the correct type and then call an instance method to alert that instance of the change.

This change handler will get called whenever the underlying dependency property is changed be that via the SetValue call in the property Set method or by binding or any other means.

like image 125
AnthonyWJones Avatar answered Jan 26 '23 19:01

AnthonyWJones