最初添加通过结合丢失藏品(Add initially missing collection item

2019-10-16 20:00发布

鉴于:

class StringRecord : INotifyPropertyChanged
{
    public string Key   { get; set; } // real INPC implementation is omitted
    public string Value { get; set; } // real INPC implementation is omitted
    ...
}

class Container
{
    public ObservableKeyedCollection<string, StringRecord> Params { get; set; }
    ...
{

ObservableKeyedCollection是在这里找到了一个 。

一个文本框绑定到收藏项目之一(DataContext的被继承):

<TextBox Text="{Binding Params[APN_HOST].Value}"/>

当我手动添加“APN_HOST”项目的收集,如预期的那样绑定工作。

现在,在这里我坚持:我希望能够编辑一个空的集合的方式,即,

如果有指定键集合中的用户类型的项,以及一些文本到文本框,这将导致添加到收藏与相应键的新项目。

我试图执行某种“默认如果没有找到”集合中的语义,但它导致所有的文本框被绑定到的同一默认实例StringRecord ,共享一个值:)

感觉就像我在这里可以俯瞰东西真的很明显。

Answer 1:

嗯,这是一个非常艰难的一个!

我所做的是:

1)长期ObservableKeyedCollection

public class ObservableKeyedCollection<TKey, TItem> : KeyedCollection<TKey, TItem>, INotifyCollectionChanged
{
    ...
    Func<TKey,TItem> m_newItemDelegate;

    public ObservableKeyedCollection(Func<TItem, TKey> getKeyForItemDelegate, Func<TKey, TItem> newItemDelegate = null)
        : base()
    {
        ...
        m_newItemDelegate = newItemDelegate;
    }

    public new TItem this[TKey key]
    {
        get
        {
            if (m_newItemDelegate != null && !Contains(key))
            {
                TItem i = m_newItemDelegate(key);
                var i_as_inpc = i as INotifyPropertyChanged;
                if (i_as_inpc != null)
                    i_as_inpc.PropertyChanged += new PropertyChangedEventHandler(AddItemOnChangeHandler);
                else
                    Add(i);
                return i;
            }
            return base[key];
        }
        set
        {
            if (Contains(key)) Remove(key);
            Add(value);
        }
    }

    private void AddItemOnChangeHandler(object sender, PropertyChangedEventArgs e)
    {
        (sender as INotifyPropertyChanged).PropertyChanged -= AddItemOnChangeHandler;
        Add((TItem)sender);
    }
  • 尽管索引被声明为new ,绑定引擎正确解析它。
  • 如果提供了新的项目,委托,我们利用它获得一些默认的项目实例缺少关键。 这个新的项目不立即添加到收藏,因为它可能侵犯后才用户实际上已经编辑它们添加值的要求。 代替,
  • 如果该项目实现了INotifyPropertyChanged ,我们勾到它PropertyChanged事件,将项目添加到从处理器的收集,并立即取消订阅PropertyChanged

仅此一点就足够了,但...一些奇怪的原因,嵌套属性通知不火!

2)改写的结合如下:

<TextBox DataContext="{Binding Params[APN_HOST]}" Text="{Binding Value}" />

现在它触发,触发上述机制!

编辑。 经过一番讨论,进行了在这里 ,我现在看到第二个修改是解决方案的不可避免的一部分,因为违约行为。 有根本没有其他的可能性,以确定哪些情况已经改变。



文章来源: Add initially missing collection items via binding