Je n'arrive pas à faire fonctionner une liaison ListBox comme prévu. J'essaye actuellement de lier un ListBox à un ObservableCollection exposé par singleton d'articles. Les éléments sont eux-mêmes une classe distincte. À l'heure actuelle, je suis RELIURE comme ceci:ListBox lié à ObservableCollection ne se met pas à jour
<Window x:Class="toxySharp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:classes="clr-namespace:MyApplication.Classes"
Title="MainWindow" Height="325" Width="400"
DataContext="{Binding Source={x:Static local:SingletonClass.Instance}}">
<Grid x:Name="LayoutRoot">
<ListBox x:Name="lstMyList" ItemsSource="{Binding Path=Objects, Mode=TwoWay}" DisplayMemberPath="Name" />
</Grid>
</Window>
Mon singleton est une implémentation de base comme celui-ci:
public class SomeObject : INotifyPropertyChanged
{
private Int32 m_vId;
private String m_vName;
public SomeObject() { }
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
public Int32 Id
{
get { return this.m_vId; }
set { this.m_vId = value; NotifyPropertyChanged("Id"); }
}
public String Name
{
get { return this.m_vName; }
set { this.m_vName = value; NotifyPropertyChanged("Name"); }
}
}
public class SingletonClass : INotifyPropertyChanged
{
private static SingletonClass m_vInstance;
private ObservableCollection<SomeObject> m_vObjects;
private SingletonClass()
{
this.m_vObjects = new ObservableCollection<SomeObject>();
for (int x = 0; x < 255; x++)
this.m_vObjects.Add(new SomeObject() { Id = x, Name = String.Format("{0} - new object", x) });
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
public static SingletonClass Instance
{
get
{
if (m_vInstance == null)
m_vInstance = new SingletonClass();
return m_vInstance;
}
}
public ObservableCollection<SomeObject> Objects
{
get { return this.m_vObjects; }
set { this.m_vObjects = value; NotifyPropertyChanged("Objects"); }
}
}
Actuellement, les travaux de liaison au démarrage. L'application liera et affichera correctement les noms de chaque objet. Par exemple ceci est une application de test faire la même mise en œuvre:
Dans ma principale application réelle que j'ai appelés méthodes async (substance Socket BeginConnect, BeginSend, etc.) qui utilisent des callbacks qui peuvent mettre à jour la collection. (C'est une liste de lecteurs donc quand certains paquets sont reçus la liste est mise à jour avec leurs données.)
Mon problème est quand la collection est mise à jour dans l'un des rappels asynchrones qu'elle ne met pas à jour dans la liste. Les données de collecte sont mises à jour correctement, la définition d'une rupture dans le code principal n'importe où montre la collection en cours de mise à jour, mais la liste ne se met jamais à jour pour refléter les modifications. Donc, il reste juste à dire la même chose, peu importe quoi.
Ai-je oublié quelque chose?
J'ai aussi essayé d'utiliser une CollectionViewSource pour permettre le filtrage et cela a le même problème.
== == EDIT
J'ai trouvé le problème qui se trouve dans le singleton avec la façon dont la collection est initialisé. Au lieu d'utiliser le membre de copie interne lors de l'initialisation de la collection, j'ai dû utiliser la propriété exposée pour lui permettre de mettre à jour l'interface utilisateur.
Donc, en utilisant ce qui suit le fixe:
private SingletonClass()
{
this.Objects = new ObservableCollection<SomeObject>();
for (int x = 0; x < 255; x++)
this.Objects.Add(new SomeObject() { Id = x, Name = String.Format("{0} - new object", x) });
}
Cependant maintenant que la liste des travaux de liaison que je veux être en mesure de filtrer cette fonction sur une autre propriété à l'intérieur de la classe d'objet. (Dans l'exemple SomeObject). J'ai un booléen indiquant si l'objet est actif. Essayer de lier une CollectionViewSource me ramène aux problèmes de non mise à jour. Donc, y a-t-il un moyen de filtrer ceci manuellement et de garder l'interface utilisateur mise à jour?
Cela ne fait rien du tout, ItemsSource est jamais changé sur la cible, il ne se propage pas à la source dans tous les cas. –
si im compréhension de l'OP correctement, alors c'est la source qui est en cours de mise à jour, mais la vue ne le voit pas. qui doit avoir un updatedsourcetrigger = propertychanged pour le réparer. Si cela ne fait rien, laissez-moi savoir quelle est votre définition de «source». dans ma tête, cela signifie que la collection observabl sur le modèle de vue – Anton
Non, 'UpdateSourceTrigger' va ** dans l'autre sens **, par ex. dans un TextBox, quand quelqu'un entre un texte, il détermine si la source à laquelle Text est lié doit être mise à jour à chaque frappe. 'ItemsControls' ne modifie pas la propriété' ItemsSource' et ne peut pas non plus être modifiée par l'utilisateur, 'UpdateSourceTrigger' ne fera jamais rien. –