2010-01-11 4 views
1

MVVM 디자인 패턴을 사용하여 WPF 응용 프로그램을 만들고 사용자가 드롭 다운 목록의 항목을 편집 할 수있는 Combobox를 만들려고합니다. 런타임, MS 액세스 2007 당신이 할 수있는 방식과 비슷합니다. 그래서 콤보 상자 위에 빌드 된 UserControl을 만들었습니다 ... 드롭 다운이 표시되면 목록의 항목을 편집 할 수있는 다른 창이 열리는 목록 아래에 단추가 있습니다. 아주 간단하지만 팝업 창은 ObservableCollection의 일부 유형이 아닌 목록의 항목 유형에 대해 아무것도 모릅니다.알 수없는 유형의 ObservableCollection에 항목 추가

HERE을 설명하려고하는 스크린 샷을 볼 수 있습니다.

예를 들어보기에서 사용자 지정 콤보 상자를 ObservableCollection<Sizes>에 바인딩합니다. 단추를 클릭하여 목록을 편집하면 팝업 창에 TextBox의 모든 항목이 표시되어 편집 할 수 있습니다. 문제는 팝업 창에서 ObservableCollection의 항목을 추가/업데이트/삭제하려고하는 것입니다. 이 창은 표시 필드의 이름 (this.DisplayMemberPath) 이외의 ObservableCollection에 대해서는 알지 못합니다.

나는 항상 combobox를 ObservableCollection<string> 또는 IEnumerable<string>에 바인딩 할 수 있다는 것을 알고 있지만 LINQ를 사용하여 SQL에 콤보 상자 항목을 채우고 있으며 모든 개체에 대한 변경 내용을 추적 할 수 있어야합니다. 목록에 작성된 변경 사항의 데이터베이스를 갱신하십시오. 따라서 변경 사항 추적을 모니터링하려면 ObservableCollection<Sizes>을 사용해야합니다 (필자 생각). CollectionChanged 이벤트를 사용하여 데이터베이스를 업데이트하는 아이디어에 놀랐지 만 클리너 메서드가 있는지 궁금합니다.

나는 Reflection을 사용하여 목록을 업데이트해야 할 필요가 있다고 느끼지만, Reflection을 사용하는 데는 정통하지 않습니다.

여기에 팝업 창을 표시하는 내 소스 코드는 다음과 같습니다

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을 사용자 지정 ComboBox에 바인딩 할 때 사용자 지정 IValueConverter를 설정하십시오. T His는 두 가지 방법, ConvertConvertBack을 정의합니다. 아이디어는 유형을 변환 할 수 있다는 것입니다.

이 경우에는 ObservableCollection<Sizes>을 가질 수 있으며 바인딩 변환기는이를 가져 와서 필요한 유형으로 변환합니다.

컬렉션 바인딩에 변환기를 설정하면 ObservableCollection<Sizes>ObservableCollection<string>으로 변환 할 수 있습니다.

다른 옵션은 IValueConverter를 내부적으로 사용자 지정 ComboBox로 설정하고 Sizes에서 string으로 변환합니다. 또 다른 옵션은 바인딩과 변환이 포함 된 itemtemplate을 특정하는 것입니다.

HtH.

+0

흠 ...이전에는 그런 식으로 ValueConverter를 사용하지 않을 생각이었습니다 ... 시도해보고 다시 돌려 드리겠습니다. 감사! – Brent

+0

내가 가진 유일한 문제는 각기 다른 유형을 포함하기 때문에 여러 종류의 ValueConverters를 사용하여 모든 종류의 콤보 상자를 작성해야한다는 것입니다. 이것은 큰 응용 프로그램이 될 것이므로 30-50 가지 유형의 목록을 가질 수 있습니다. 정말 반사가 갈 방법이라고 생각하지만, 그것을 구현하는 방법을 모르겠다. – Brent

+0

음, 분명히 그것을 바꿀 것입니다. 목록에있는 각 개체는 사용자 지정 작성됩니까? –

2

목록에 대해 알아야 할 것 같지만 특정 유형이 아닌 것 같습니다. 바로 비 제네릭 인터페이스가 들어오는 곳입니다. 더 일반적인 경우 등 (알림),

INotifyCollectionChanged을 (등 추가/제거/모든 인덱서를 가지고있는) IList으로 목록을 액세스 해보십시오 또한 IBindingList/IBindingListView/ITypedList 등이 있습니다,하지만 난 돈 ' 이 경우에는 당신이 필요하다고 생각하지 않습니다.

+0

이것을 구현하는 방법을 잘 모르겠습니다. 코드 예제를 제공 할 수 있습니까? – Brent

관련 문제