Je crée une application WPF en utilisant le modèle de conception MVVM, et j'essaye de créer une Combobox qui permet à l'utilisateur de modifier les éléments dans la liste déroulante à runtime, similaire à la façon dont MS Access 2007 vous permet de le faire. J'ai donc créé un UserControl qui se construit au-dessus d'une Combobox ... lorsque la liste déroulante est affichée, il y a un bouton sous la liste qui ouvre une autre fenêtre pour éditer les éléments de la liste. Assez simple, mais la fenêtre contextuelle ne sait rien sur le type d'éléments dans la liste, à part qu'ils sont d'un type ObservableCollection.Ajout d'un élément à un ObservableCollection d'un type inconnu
Vous pouvez voir une capture d'écran de ce que j'essaie d'expliquer HERE.
Par exemple, dans la vue, je lie la liste déroulante personnalisée à ObservableCollection<Sizes>
. Je clique sur le bouton pour éditer la liste et la fenêtre popup affiche tous les éléments dans un TextBox pour que l'utilisateur édite. Le problème est d'essayer d'ajouter/mettre à jour/supprimer des éléments dans ObservableCollection à partir de la fenêtre contextuelle. Cette fenêtre ne sait rien sur ObservableCollection, autre que le nom du champ d'affichage (this.DisplayMemberPath). Je sais que je pourrais toujours lier la combobox à un ObservableCollection<string>
, ou IEnumerable<string>
, mais j'utilise LINQ to SQL pour remplir les éléments de la liste déroulante, et je dois être conscient du suivi des changements sur tous mes objets afin que je puisse mettre à jour la base de données des modifications apportées à la liste. Par conséquent, (je pense) je dois utiliser ObservableCollection<Sizes>
afin de surveiller le suivi des changements. J'ai aussi joué avec l'idée d'utiliser l'événement CollectionChanged pour mettre à jour la base de données, mais je me demande s'il existe une méthode plus propre.
J'ai le sentiment que je vais avoir besoin d'utiliser Reflection pour mettre à jour la liste, mais je ne suis pas très versé dans l'utilisation de Reflection.
Voici mon code source pour afficher la fenêtre:
public event EventHandler<EventArgs> EditListClick;
private void EditButton_Click(object sender, RoutedEventArgs e)
{
if (this.EditListDialog == null)
{
// Create the default dialog window for editing the list
EditListDialogWindow dialog = new EditListDialogWindow();
string items = string.Empty;
if (this.Items != null)
{
// Loop through each item and flatten the list
foreach (object item in this.Items)
{
PropertyInfo pi = item.GetType().GetProperty(this.DisplayMemberPath);
string value = pi.GetValue(item, null) as string;
items = string.Concat(items, ((items == string.Empty) ? items : "\n") + value);
}
// Now pass the information to the dialog window
dialog.TextList = items;
}
// Set the owner and display the dialog
dialog.Owner = Window.GetWindow(this);
dialog.ShowDialog();
// If the user has pressed the OK button...
if (dialog.DialogResult.HasValue && dialog.DialogResult.Value)
{
// Make sure there has been a change
if (items != dialog.TextList)
{
// Unflatten the string into an Array
string[] itemArray = dialog.TextList.Split(new string[]{"\n", "\r"}, StringSplitOptions.RemoveEmptyEntries);
// Add the items to the list
foreach (string item in itemArray)
{
// This is where I run into problems...
// Should I be using reflection here??
((ObservableCollection<object>)this.ItemsSource).Add(item.Trim());
}
}
}
}
if (EditListClick != null)
EditListClick(this, EventArgs.Empty);
}
Hmm ...Je n'avais pas pensé à utiliser un ValueConverter de cette façon avant ... Je vais essayer et revenir avec vous. Merci! – Brent
Le seul problème que j'ai avec cela est que cela m'obligerait à écrire un tas de ValueConverters pour chaque type de combobox que j'utilise, car chacun contiendrait un type différent. Ce sera une grande application, donc je pourrais avoir 30-50 différents types de listes. Je pense vraiment que la réflexion est la voie à suivre, mais je ne sais pas comment l'implémenter ... – Brent
Hmmm, ça change certainement. Chacun de ces objets dans les listes sera-t-il personnalisé? –