Frage

Ich habe diese DependencyProperty, die eine Einheit mit einer Eigenschaft enthält, die eine Sammlung (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); }
}

Es binded wird in xaml wie so:

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

Als ich es das erste Mal binden, es funktioniert wie erwartet, aber es gibt Zeiten, wenn ich Elemente in die Sammlung hinzufügen muß (mit einem Verfahren, das in der gleichen Kontrolle ist), wie solche:

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

Das Problem ist, dass, wenn ich ein neues Element mit dem obigen Verfahren hinzufügen, wird das Element nicht in den ItemsControl angezeigt wird.


Meine Frage ist, warum nicht das neue Element, das ich das Hinzufügen bin nicht in den ItemsControl angezeigt wird,


[Bearbeiten]

Entries ( ShoutBox.Entries ) vom Typ List<ShoutBoxEntry>

War es hilfreich?

Lösung

Was ist die Art der Einträge? Es muss entweder ObservableCollection oder implementieren ICollectionChanged sein. Ansonsten ist die Bindung nicht weiß, dass ein neues Element hinzugefügt worden ist.

Andere Tipps

Die Änderung der Einträge sollte in der Tat das Problem lösen ... Wenn Sie den expliziten Aufruf Dispatcher.Invoke vermeiden wollen, schrieb ich eine Sammlung, die die Collection und Property Ereignisse auf dem Thread aufwirft, die die Sammlung erstellt:

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

Weitere Informationen finden Sie hier: http://www.thomaslevesque.com / 2009/04/17 / wpf-binding-to-an-asynchron-Sammlung /

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top