Pergunta

Eu tenho essa DependencyProperty que detém uma entidade com uma propriedade que é uma coleção (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); }
}

Está a ser binded em xaml como tal:

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

Quando eu ligá-la pela primeira vez, ele funciona como esperado, mas há momentos em que eu preciso adicionar itens à coleção (com um método que está na mesma controle), como tal:

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

O problema é que quando eu adicionar um novo elemento com o método acima, o item não está sendo exibido no ItemsControl.


A minha pergunta é, por que não é o novo elemento que estou adicionando não está sendo exibido no ItemsControl ?


[Edit]

Entries ( ShoutBox.Entries ) é do tipo List<ShoutBoxEntry>

Foi útil?

Solução

O que é o tipo de inscritos? Ele quer precisa ser ObservableCollection ou implementar ICollectionChanged. Caso contrário, a ligação não sabe que um novo item foi adicionado.

Outras dicas

A alteração do tipo de inscritos deve realmente resolver o problema ... Se você quiser evitar a chamada explícita para Dispatcher.Invoke, eu escrevi uma coleção que gera os eventos CollectionChanged e PropertyChanged no segmento que criou a coleção:

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

Mais detalhes podem ser encontrados aqui: http://www.thomaslevesque.com / 2009/04/17 / WPF de ligação-a-um-assíncrona de coleta /

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top