2010-01-11 55 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