代码之家  ›  专栏  ›  技术社区  ›  James Hughes

未调用绑定属性setter

  •  4
  • James Hughes  · 技术社区  · 14 年前

    我对以下场景有一个问题(为了简洁而进行代码剪切)。基本上,当设置依赖属性时,不会调用用户控件属性的setter,我需要解决这个问题。

    我的视图中有以下代码.xaml

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

    在view.xaml.cs中

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

    在我的ViewModel中,我公开了一个属性

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

    最后,过滤器用户控件的定义是这样的。

       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);
            }
        }
    

    出于某种原因,设置了primaryitemsource属性,但没有调用setter。我是否需要向PropertyMetadata对象添加一个PropertyChange事件来处理这个问题,因为这看起来像是许多简单的代码。

    3 回复  |  直到 14 年前
        1
  •  3
  •   herzmeister    14 年前

    是的,如果需要附加的setter逻辑,请始终使用回调。这是一个 必须 在Silverlight和WPF中。

    据我所知,只有在实际从代码中使用时,才会调用setter。进行绑定时,使用DependencyProperty框架会发生一些事情。

    你也应该把你的 ComboBox combo = ... 代码转换为 this.Dispatcher.BeginInvoke(() => ... ); 因为这样可以确保可视化树被初始化。

        2
  •  5
  •   AnthonyWJones    14 年前

    这就是需要在集合上运行其他代码的依赖项属性的编写方式:

     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); 
     }
    

    使用将静态DependencyPropertyChanged处理程序放置在类中,该类将依赖项对象强制转换为正确的类型,然后调用实例方法通知该实例更改。

    每当基础依赖项属性更改为通过 SetValue 收回财产 Set 方法、约束或任何其他方法。

        3
  •  1
  •   Michael S. Scherotter    14 年前

    dependencyProperty.register()方法的最后一个参数接受传递空值的PropertyMetadata。构造函数的一个重载接受PropertyChangedCallback。使用此重载定义一个回调函数,该函数将在修改属性时调用。

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