简体   繁体   中英

PropertyChangedCallback on DependencyProperty Only Firing Once

I have the exact problem as this guy in the Silverlight Forum and the accepted answer is :

In this case, your property didn't actually change value. You added something to your List, but the list is the same List so when the DependencyProperty mechanism sees that the actual value (reference to your List) didn't change, it didn't raise your OnChanged handler

This is a great explication but not an answer to fix this problem. I can find on Google many suggestion for WPF but not for Silverlight.

The problem is describe as this one : You have a DependencyProperty that is called when the variable is initialized but after then nothing is updated.

public partial class MyGrid : UserControl
{
    public MyGrid()
    {
        InitializeComponent();
    }

    public static readonly DependencyProperty ShapesProperty = DependencyProperty.Register(
          "Shapes", typeof(ObservableCollection<ModelItem>), typeof(MyGrid), new PropertyMetadata(OnShapesPropertyChanged));

    public ObservableCollection<ModelItem> Shapes
    {
        private get { return (ObservableCollection<ModelItem>)GetValue(ShapesProperty); }
        set { SetValue(ShapesProperty, value); }
    }

    private static void OnShapesPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
    {
        ((MyGrid)o).OnShapesPropertyChanged(e); //Fire Only Once
    }

    private void OnShapesPropertyChanged(DependencyPropertyChangedEventArgs e)
    {
        dg.ItemsSource = e.NewValue as ObservableCollection<ModelItem>;
    }


}

//--------
public class ViewModel : INotifyPropertyChanged
{
    public Model Model { get; set; }
    public RelayCommand cmd;
    public ObservableCollection<ModelItem> ModelItemCollection
    {
        get
        {
            return  Model.ModelItem;
        }
    }

    public ViewModel()
    {
        Model = new Model();
        Model.PropertyChanged += Model_PropertyChanged;
    }

    void Model_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {

        System.Diagnostics.Debug.WriteLine(e.PropertyName);

        if (PropertyChanged != null)
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs("ModelItemCollection"));
        }
    }

    public ICommand AddCmd
    {
        get { return cmd ?? (cmd = new RelayCommand(a => Model.ModelItem.Add(new ModelItem {Name = "asd"}))); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

///----------------------

public class Model: INotifyPropertyChanged
{
    public ObservableCollection<ModelItem> ModelItem { get; set; }

    public Model()
    {
        ModelItem = new ObservableCollection<ModelItem>();
        ModelItem.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(ModelItem_CollectionChanged);
    }

    void ModelItem_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        if (PropertyChanged != null)
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs("ModelItem"));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

public class ModelItem
{
    public String Name { get; set; }
}

Even with explicit call of PropertyChanged() nothing is updated.

What is the workaround to let know the DependencyProperty that the ObservableCollection has elements that have changed?

Pseudocode:

BindingOperations.GetBindingExpressionBase(dependencyObject, dependencyProperty).UpdateTarget();

Look here: forcing a WPF binding to 'refresh' ...

Try this, usually works :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM