I'm creating a WPF application using the MVVM design pattern, and I'm trying to create a Combobox that allows the user to edit the items in the drop-down list at runtime, similar to the way MS Access 2007 lets you do it. So I've created a UserControl that builds on top of a Combobox... when the drop-down is shown, there is a button below the list that opens another window to edit the items in the list. Pretty straight forward, but the popup window knows nothing about the type of items in the list, other than they are of some type of an ObservableCollection.
You can view a screenshot of what I'm trying to explain HERE.
For instance, on the View, I bind the custom combobox to ObservableCollection<Sizes>
. I click the button to edit the list and the popup window displays all of the items in a TextBox for the user to edit. The problem is trying to add/update/delete items in the ObservableCollection from the popup window. This window does not know anything about the ObservableCollection, other than the name of the display field (this.DisplayMemberPath).
I know that I could always bind the combobox to an ObservableCollection<string>
, or IEnumerable<string>
, but I am using LINQ to SQL to populate the combobox items, and I need to be aware of change tracking on all of my objects so I can update the database of changes made to the list. Therefore, (I think) I must use ObservableCollection<Sizes>
in order to monitor change tracking. I've also toyed with the idea of using the CollectionChanged Event to update the database, but I'm wondering if there is a cleaner method.
I have a feeling that I'll be needing to use Reflection to update the list, but I'm not very well versed in working with Reflection.
Here's my source code for displaying the popup window:
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);
}