2010-01-11 41 views
1

我使用MVVM设计模式创建一个WPF应用程序,我试图创建一个组合框,允许用户在编辑的下拉列表中的项目的一个ObservableCollection运行时间,类似于MS Access 2007让你这样做的方式。所以我创建了一个构建在Combobox之上的UserControl ...当显示下拉列表时,列表下方会有一个按钮打开另一个窗口来编辑列表中的项目。非常简单,但弹出窗口对列表中的项目类型一无所知,除了它们是某种类型的ObservableCollection。添加项目到一个未知类型

您可以查看什么,我试图解释HERE截图。

例如,打开查看,我自定义组合框绑定到ObservableCollection<Sizes>。我点击按钮编辑列表,弹出窗口显示用户编辑的文本框中的所有项目。问题是试图从弹出窗口中添加/更新/删除ObservableCollection中的项目。除了显示字段的名称(this.DisplayMemberPath)外,此窗口不知道ObservableCollection的任何内容。

我知道我总是可以将组合框绑定到ObservableCollection<string>IEnumerable<string>,但我使用LINQ to SQL来填充组合框项目,并且我需要知道所有对象上的更改跟踪,所以我可以更新对列表所做更改的数据库。因此,(我认为)我必须使用ObservableCollection<Sizes>来监控变更跟踪。我也玩过使用CollectionChanged事件来更新数据库的想法,但我想知道是否有更清晰的方法。

我有你们需要使用反射来更新列表中的感觉,但我不是在与反思工作十分精通。

下面是显示在弹出的窗口我的源代码:

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

回答

0

您是否尝试过使用IValueConverter

当您将ObservbleCollection绑定到自定义组合框时,请设置自定义IValueConverter。 T他定义了2种方法,ConvertConvertBack。这个想法是,你可以转换类型。

在这种情况下,你可以有你ObservableCollection<Sizes>,并结合转换器将采取并将其转换为所需要的类型。

如果设置在收集器结合,你可以转换,并从ObservableCollection<Sizes>ObservableCollection<string>

另一个选项是将IValueConverter内部设置为自定义组合框,并执行从Sizesstring的转换。另一个选项是结合特定的itemtemplate来包含绑定和转换。

HtH。

+0

嗯......我没有想过用这种方式使用ValueConverter之前...我会试一试,然后和你一起回去。谢谢! – Brent 2010-01-11 14:02:22

+0

我唯一的问题是,它会要求我为每种类型的组合框编写一组ValueConverters,因为每个组合框都包含不同的类型。这将是一个大型应用程序,所以我可以有30-50种不同类型的列表。 我真的认为反思是要走的路,但我不知道如何实施它...... – Brent 2010-01-11 20:39:04

+0

嗯,这确实会改变它。这些列表中的每个对象是否都是自定义的? – 2010-01-12 01:18:38

2

这听起来像你需要知道列表,但不是特定的类型。这就是非通用接口进入的地方;尝试访问列表为IList(其中包含所有索引/添加/删除等),INotifyCollectionChanged(用于通知)等

在更一般的情况下也有IBindingList/IBindingListView/ITypedList等,但我不我认为你在这种情况下需要这些。

+0

我不知道我明白如何实现这一点。你能提供一个代码示例吗? – Brent 2010-01-11 20:36:30

相关问题