2011-08-09 2 views
6

Pracuję nad wewnętrznym programem śledzącym oprogramowanie, a każdej wersji programu przypisuje się programistę wiodącego z bazy danych pracowników. Mój prosty model wygląda to tak daleko:Jak powiązać powiązanie Entity Framework z ComboBox?

Entity Framework model

Początkowo miałem RevisionBindingSource przedmiot, który był związany z moim Revisions kolekcji:

Dim container as new EntityContainer 
revisionBindingSource.DataSource = container.Revisions 
... 
dgRevisions.DataSource = revisionBindingSource 
dgRevisions.DataMemeber = "" 

To działa dobrze, a ja byłem w stanie wiązać się różne wymagane właściwości, takie jak tytuł aplikacji:

lblAppTitle.DataBindings.Add("Text",revisionBindingSource,"Application.Title") 

Jednak teraz potrzebuję Co mboBox, którego pozycje są powiązane z listą pracowników, i których wybrana wartość jest związana z głównym programistą aktualnej wersji. Próbowałem tworzenia nowego employeeBindingSource, ale uświadomiłem sobie, że nie mają wiążącego dla Value:

employeeBindingSource.DataSource = container.Employees 
... 
cboLead.DataSource = employeeBindingSource 
cboLead.DisplayMember = "Name.Display" 'Name is a complex type' 
cboLead.ValueMember = '?? 

Więc przepisał kilka moich wiązań mieć tylko jeden bindingSource:

bindingSource.DataSource = container 
... 
dgRevisions.DataSource = bindingSource 
dgRevisions.DataMemeber = "Revisions" 
... 
cboLead.DataSource = bindingSource 
cboLead.DisplayMember = "Employees.Name.Display" 
cboLead.ValueMember = "Employees" 
... 
lblAppTitle.DataBindings.Add("Text",bindingSource,"Revisions.Application.Title") 

to nadal nie nawet zapełnić ComboBox czymkolwiek.

Który wzór jest lepszy dla mnie - dwa różne źródła wiążące lub jeden? Co robię źle w wiązaniu mojego ComboBox? A kiedy zapełni się mój ComboBox, w jaki sposób mogę powiązać aktualną wartość z głównym programistą rewizji?

Przepraszamy za długotrwałe pytanie i dziękuję.

+0

+1 za miłą prezentacji swojej Pytanie –

+1

Co ram UI używasz. WinForms? Dodaj tag, aby uzyskać lepsze odpowiedzi. –

+0

Niektóre płatne kontrole robią to (używam DevExpress i pozwala to zrobić). Możesz rozważyć napisanie niestandardowego combobox, który rozciąga się od zwykłego combobox i który zwraca to, czego potrzebujesz. –

Odpowiedz

3

Nie ma nic złego w posiadaniu więcej niż jednego źródła wiążącego w formularzu. W rzeczywistości, "wiązania" źródeł wiążących takich jak Ty sugerujesz powyżej może być wygodną strategią.

W tej sytuacji brakuje jednak łącza, które należy wypełnić, aby powiązać właściwość .Value z rzeczywistym obiektem EF: należy utworzyć oddzielną klasę dla celów wiązania. Ta technika jest również bardzo przydatna podczas wiązania z wyliczeniami.

Ta technika jest bardzo powszechna, gdy model danych EF nie odpowiada dokładnie temu, jak chcesz, aby Twój interfejs działał. W przypadku WPF (nie WinForms, jak w tym przykładzie), jest to często określane jako część ViewModel. Po wykonaniu tego kilka razy, stanie się to drugą naturą.

Oto próbka implementacja klasy trzeba będzie utworzyć:

public class EmployeeBindingObject 
{ 
    public Employee Employee { get; private set; } 
    public string EmployeeName 
    { 
     get { return this.Employee.Name; } 
    } 

    private EmployeeBindingObject(Employee employee) 
    { 
     this.Employee = employee; 
    } 

    /// <summary> 
    /// Gets a binding list for a specified list of Employees. 
    /// </summary> 
    /// <param name="types"></param> 
    /// <returns></returns> 
    public static IBindingList GetBindingList(IEnumerable<Employee> employees) 
    { 
     BindingList<EmployeeBindingObject> result = new BindingList<EmployeeBindingObject>(); 

     foreach (var ee in employees) 
     { 
      result.Add(new EmployeeBindingObject(ee)); 
     } 

     return result; 
    } 
} 

Po utworzeniu tej klasy, należy skompilować, a następnie utworzyć źródło danych (Dane -> Dodaj nowe źródło danych .. .) dla EmployeeBindingObject.

  1. Ustawić ValueMember do Employee
  2. Ustaw DisplayMember do EmployeeName
  3. ustawić właściwość do Employee własności swojej drugiej BindingSource za SelectedValue.
  4. Następnie w kodzie, musisz zainicjować wiążącą obiektu BindingSource następująco:

    employeeBindingObjectBindingSource.DataSource = 
        EmployeeBindingObject.GetBindingList(container.Employees)