代码之家  ›  专栏  ›  技术社区  ›  Brent

向未知类型的ObservableCollection添加项

  •  1
  • Brent  · 技术社区  · 15 年前

    我正在使用MVVM设计模式创建一个WPF应用程序,我正在尝试创建一个组合框,允许用户在运行时编辑下拉列表中的项目,类似于MS Access 2007允许您这样做的方式。所以我创建了一个基于组合框的用户控件…显示下拉列表时,列表下方有一个按钮,打开另一个窗口以编辑列表中的项目。非常直接,但是弹出窗口对列表中的项目类型一无所知,除了它们是某种可观察的集合。

    你可以查看我要解释的内容的屏幕截图 HERE .

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

    我知道我可以将组合框绑定到 ObservableCollection<string> IEnumerable<string> ,但我正在使用Linq to SQL填充组合框项,我需要了解所有对象的更改跟踪,以便更新对列表所做更改的数据库。因此,(我想)我必须使用 可观察收集<尺寸> 以便监控变更跟踪。我还玩弄使用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);
    }
    
    2 回复  |  直到 15 年前
        1
  •  0
  •   Alastair Pitts    15 年前

    你试过用 IValueConverter ?

    将ObservbleCollection绑定到自定义组合框时,请设置自定义IValueConverter。这定义了两种方法, Convert ConvertBack . 其思想是,您可以转换类型。

    在这种情况下,您可以 ObservableCollection<Sizes> 绑定转换器将获取该类型并将其转换为所需的类型。

    如果在集合绑定上设置转换器,则可以转换为 可观察收集<尺寸> ObservableCollection<string> .

    另一个选项是在内部将ivalueConverter设置为自定义组合框,并从 Sizes string . 另一个选项,结合使用是指定包含绑定和转换的项模板。

    Hth.

        2
  •  2
  •   Marc Gravell    15 年前

    听起来你需要知道这个列表,但不知道具体的类型。这就是非通用接口出现的地方;尝试访问列表 IList (包含所有索引器/添加/删除等) INotifyCollectionChanged (用于通知)等。

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