Je rencontre un problème avec un ObservableCollection qui obtient de nouveaux éléments mais ne reflète pas ces modifications dans un ListView. J'ai assez de bizarreries dans la façon dont je suis en train de mettre en œuvre cela que j'ai du mal à déterminer quel est le problème.ObservableCollection <T> ne pas mettre à jour l'interface utilisateur
Mon ObservableCollection est mis en œuvre ainsi:
public class MessageList : ObservableCollection<LobbyMessage>
{
public MessageList(): base()
{
Add(new LobbyMessage() { Name = "System", Message = "Welcome!" });
}
}
je stocke la collection dans une propriété statique (de sorte que son facilement accessible à partir de plusieurs contrôles utilisateur):
static public MessageList LobbyMessages { get; set; }
En cas OnLoad de mon La principale NavigationWindow j'ai la ligne suivante:
ChatHelper.LobbyMessages = new MessageList();
Mon X AML dans le UserControl où le ListView est situé se lit comme:
<ListBox IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding Mode=OneWay}"
x:Name="ListBoxChatMessages"
d:UseSampleData="True"
ItemTemplate="{DynamicResource MessageListTemplate}"
IsEnabled="True">
<ListBox.DataContext>
<Magrathea_Words_Tools:MessageList/>
</ListBox.DataContext>
</ListBox>
Le message initial que j'ai ajouté dans le constructeur apparaît dans l'interface utilisateur très bien.
Maintenant, la façon dont j'ajoute de nouveaux éléments à la collection provient d'un CallBack provenant d'un service WCF. J'ai eu ce code fonctionnant dans une application WinForms et il était nécessaire de marshall le rappel au fil de l'interface utilisateur donc j'ai laissé ce code en place. Voici une version abrégée de la méthode:
Helper.Context = SynchronizationContext.Current;
#region IServiceMessageCallback Members
/// <summary>
/// Callback handler for when the service has a message for
/// this client
/// </summary>
/// <param name="serviceMessage"></param>
public void OnReceivedServiceMessage(ServiceMessage serviceMessage)
{
// This is being called from the WCF service on it's own thread so
// we have to marshall the call back to this thread.
SendOrPostCallback callback = delegate
{
switch (serviceMessage.MessageType)
{
case MessageType.ChatMessage:
ChatHelper.LobbyMessages.Add(
new LobbyMessage()
{
Name = serviceMessage.OriginatingPlayer.Name,
Message = serviceMessage.Message
});
break;
default:
break;
}
};
Helper.Context.Post(callback, null);
}
Pendant que je débogage peux voir la collection se mis à jour avec des messages du service, mais l'interface utilisateur ne reflète pas ces ajouts.
Des idées sur ce qui me manque pour que le ListView reflète ces nouveaux éléments de la collection?
Si je comprends bien, l'intention de MS en WPF était de faire des choses comme mettre des sources contraignantes (comme la propriété ItemsSource) un paramètre de données statiques dans le XAML, plutôt que dans le code. Un développeur plus expérimenté refait mon programme complexe avec presque aucun C#, et seulement un peu plus de xaml. xaml> code. –