WPF: Add Item to Data Collection (Dependency Property)

I have this DependencyProperty

one which contains an object with a property that is a collection ( ShoutBox.Entities

):

public static readonly DependencyProperty ShoutBoxProperty = DependencyProperty.Register("ShoutBox",typeof (ShoutBox),typeof (ShoutBoxViewerControl));

public ShoutBox ShoutBox
{
    get { return (ShoutBox) GetValue(ShoutBoxProperty); }
    set { SetValue(ShoutBoxProperty, value); }
}

      

It is tied to xaml

this way:

<ItemsControl ItemsSource="{Binding ShoutBox.Entries}">
.
.
</ItemsControl>

      

When I link it the first time, it works as expected, but there are times when I need to add items to the collection (using a method that is in the same control), for example:

public void AddNewEntry(ShoutBoxEntry newEntry)
{
    Dispatcher.Invoke(new Action(() =>{
        ShoutBox.Entries.Add(newEntry); //Adding directly the the Dependency property
    }));
}

      

The problem is that when I add a new item with the above method, the item is not displayed in ItemsControl

.


My question is: Why isn't the new item I'm adding showing up inItemsControl

?


[change]

Entries

(ShoutBox.Entries) is of type List<ShoutBoxEntry>

+1


a source to share


2 answers


What is the post type? It must either be an ObservableCollection or implement ICollectionChanged. Otherwise, the binding does not know that a new item has been added.



+3


a source


Changing the post type should really solve the problem ... If you want to avoid explicitly calling Dispatcher.Invoke, I wrote a collection that raises the CollectionChanged and PropertyChanged events on the thread that created the collection:

public class AsyncObservableCollection<T> : ObservableCollection<T>
{
    private SynchronizationContext _synchronizationContext = SynchronizationContext.Current;

    public AsyncObservableCollection()
    {
    }

    public AsyncObservableCollection(IEnumerable<T> list)
        : base(list)
    {
    }

    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        if (SynchronizationContext.Current == _synchronizationContext)
        {
            // Execute the CollectionChanged event on the current thread
            RaiseCollectionChanged(e);
        }
        else
        {
            // Post the CollectionChanged event on the creator thread
            _synchronizationContext.Post(RaiseCollectionChanged, e);
        }
    }

    private void RaiseCollectionChanged(object param)
    {
        // We are in the creator thread, call the base implementation directly
        base.OnCollectionChanged((NotifyCollectionChangedEventArgs)param);
    }

    protected override void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        if (SynchronizationContext.Current == _synchronizationContext)
        {
            // Execute the PropertyChanged event on the current thread
            RaisePropertyChanged(e);
        }
        else
        {
            // Post the PropertyChanged event on the creator thread
            _synchronizationContext.Post(RaisePropertyChanged, e);
        }
    }

    private void RaisePropertyChanged(object param)
    {
        // We are in the creator thread, call the base implementation directly
        base.OnPropertyChanged((PropertyChangedEventArgs)param);
    }
}

      



More information can be found here: http://www.thomaslevesque.com/2009/04/17/wpf-binding-to-an-asynchronous-collection/

0


a source







All Articles