BindingProxy: binding to the indexed property

狂风中的少年 提交于 2019-11-28 02:20:20

EDIT:

It is an error for sure:

PropertyChanged(null, new PropertyChangedEventArgs("ColumnsVisibility"));

It should be:

PropertyChanged(this, new PropertyChangedEventArgs("ColumnsVisibility"));

I have blindly copied it into my first edit from your code. Well, sometimes you just don't see the things before your eyes

For future I recommend you to use some sort of a function in some base class like

public class NotifyPropertyChangeableBase: INotifyPropertyChanged // Usually I name it somewhat like 'ViewModelBase' in my projects, but your actual class is the control, so it is not the most appropriate name
{
    protected void OnPropertyChanged(String propertyName)
    {
        if (this.PropertyChanged != null)
            this.PropertyChanged(this,
                new PropertyChangedEventArgs(propertyName));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

It did not solve the issue, but it is at least one problem down

EDIT WITH(I HOPE) THE FINAL SOLUTION:

It looks that you cannot notify the WPF engine that your dictionary has changed its items. And standard Dictionary does not do it on its own(it does not implement the ICollectionChanged or even INotifyPropertyChanged).

That's why you have to use your own dictionary, or to be more precise wrapper dictionary class:

public class DictionaryNotificationWrapper<TKey, TValue> : IDictionary<TKey, TValue>, INotifyPropertyChanged
{
    #region Fields

    private IDictionary<TKey, TValue> innerDictionary;

    #endregion



    #region Constructors

    public DictionaryNotificationWrapper(IDictionary<TKey, TValue> innerDictionary)
    {
        if (innerDictionary == null)
            throw new ArgumentNullException("innerDictionary", "The inner dictionary is null");

        this.innerDictionary = innerDictionary;
    }

    #endregion



    #region IDictionary implementation

    public TValue this[TKey key]
    {
        get
        {
            return this.innerDictionary[key];
        }
        set
        {
            this.innerDictionary[key] = value;

            this.OnPropertyChanged("Item[]");
            this.OnPropertyChanged("Count");
        }
    }

    #endregion



    #region not implemented IDictionary members - you are free to finish the work

    public void Add(TKey key, TValue value)
    {
        throw new NotImplementedException();
    }

    public bool ContainsKey(TKey key)
    {
        throw new NotImplementedException();
    }

    public ICollection<TKey> Keys
    {
        get { throw new NotImplementedException(); }
    }

    public bool Remove(TKey key)
    {
        throw new NotImplementedException();
    }

    public bool TryGetValue(TKey key, out TValue value)
    {
        throw new NotImplementedException();
    }

    public ICollection<TValue> Values
    {
        get { throw new NotImplementedException(); }
    }


    public void Add(KeyValuePair<TKey, TValue> item)
    {
        throw new NotImplementedException();
    }

    public void Clear()
    {
        throw new NotImplementedException();
    }

    public bool Contains(KeyValuePair<TKey, TValue> item)
    {
        throw new NotImplementedException();
    }

    public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
    {
        throw new NotImplementedException();
    }

    public int Count
    {
        get { throw new NotImplementedException(); }
    }

    public bool IsReadOnly
    {
        get { throw new NotImplementedException(); }
    }

    public bool Remove(KeyValuePair<TKey, TValue> item)
    {
        throw new NotImplementedException();
    }

    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
    {
        throw new NotImplementedException();
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        throw new NotImplementedException();
    }

    #endregion



    #region INotifyPropertyChanged implementation


    public event PropertyChangedEventHandler PropertyChanged;


    protected void OnPropertyChanged(String propertyName)
    {
        if (this.PropertyChanged != null)
            this.PropertyChanged(this,
                new PropertyChangedEventArgs(propertyName));
    }

    #endregion
}

With such a class:

/// <summary>
/// Interaction logic for HyperVControl.xaml
/// </summary>
public partial class HyperVControl : UserControl, INotifyPropertyChanged
{
    #region Constructors

    public HyperVControl()
    {
        // Form initialization
        InitializeComponent();

        // Initialize columns visibility collection
        IDictionary<String, Boolean> innerColumnsVisibilityDictionary = new Dictionary<String, Boolean>();
        innerColumnsVisibilityDictionary.Add("ElementName", true);
        // Wrap the visibility dictionary
        this.ColumnsVisibility = new DictionaryNotificationWrapper<String, Boolean>(innerColumnsVisibilityDictionary);

        // Initialize grid's datasource
        this.HVMachineList = new ObservableCollection<HyperVMachine>();
        this.HVMachineList.Add(new HyperVMachine());
        this.HVMachineList.Add(new HyperVMachine());
        this.HVMachineList.Add(new HyperVMachine());
    }

you will be able to notify your visual components without any code-behind.

P.S.: I have implemented INotifyProperyChanged that notifies about the changes in Item[] indexed property, but you could try to implement INotifyCollectionChanged interface - I am just unsure how it will work with indexed bindings.
P.P.S.: I haven't seen your comment that you have found this.PropertyChanged(this, new ... issue.
P.P.P.S.: If you have time then change the question title to "BindingProxy: binding to the indexed property" to better reflect the problem and leave only the code from the last edit(to avoid duplication) - think of it as the community service.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!