2016-04-15 16 views
2

Ich habe eine Combobox mit einer Liste als Datenquelle. Diese Liste enthält Objekte (Kunden) mit ihren Eigenschaften (Name, Adresse, ...). Wenn ich ein Element der Combobox auswähle, möchte ich die Informationen (Adresse, Postleitzahl ...) an einige Textfelder in meinem Formular weitergeben. In meinem Test 1tier Anwendung funktioniert das richtig. Aber die Hauptanwendung, die ich arbeite, basiert auf MVP (mit meiner eigenen Berührung darauf). Das Problem, dem man sich gegenübersieht, ist das Gießen. Da meine Ansicht mein Modell nicht kennt, sollte ich die (Kunden) nicht verwenden dürfen. string address = ((Customers)comboBox1.SelectedItem).CustomerAddress;MVP Winforms und Textfeld Combobox Werte

1fach Testcode:

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) 
{ 
    //getCustomers((int)comboBox1.SelectedValue); 
    //txtAddress.Text =Convert.ToString(comboBox1.SelectedValue); 
    Customers p = (Customers)comboBox1.SelectedItem; 
    string s = comboBox1.SelectedItem.ToString(); 
    string address = ((Customers)comboBox1.SelectedItem).CustomerAddress; 
    txtAddress1.Text = address; 
} 

private void Form3_Load(object sender, EventArgs e) 
{ 
    using (var emp = new EmployerEFEntities()) 
    { 
     var query = from customers in emp.Customers 
        select customers; 

     comboBox1.DisplayMember = "CustomerName"; 
     comboBox1.ValueMember = "CustomerID"; 
     comboBox1.DataSource = query.ToList(); 
    } 
} 

Ich habe jetzt um diese für ein paar Tage suchen, sondern haben zu einem Erfolg kommen. Ich hoffe, jemand könnte mir die richtige Richtung geben.

Der Code der realen Anwendung:

Ausblick:

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) 
{ 
    txtName.Text = comboBox1.SelectedValue.ToString(); 
} 

private void CustomerView_Load(object sender, EventArgs e) 
{ 
    comboBox1.DataSource = customerPresenter.getCustomers(); 
    comboBox1.DisplayMember = "CustomerName"; 
    comboBox1.ValueMember = "CustomerId"; 
} 

Moderator:

public List<tbl_customer> getCustomers() 
{ 
    using (var customers = new DBCrownfishEntities()) 
    { 
     var customer = from c in customers.tbl_customer 
         select c; 

     return customer.ToList(); 
    } 
} 

Antwort

2

Dies ist nur eine Möglichkeit, es zu implementieren. Ihr MVP-Muster sieht möglicherweise anders aus. In dieser Implementierung kennt die View den Presenter. Weitere Informationen zum MVP können Sie einen Blick here

Sie den Presenter als Wrapper für Ihre Kunden verwenden können:

public interface IPresenter 
{ 
    void Init(); 
    void SetSelectedCustomer(int customerId); 
    IEnumerable GetCustomers(); 
    string FirstName { get; set; } 
    string LastName { get; set; } 
    string Address { get; set; } 
} 

Der Moderator muss implementieren INotifyPropertyChanged (und rufen OnPropertyChanged in den Property-Setter).

public class Presenter : IPresenter, INotifyPropertyChanged 
{ 
    private readonly Repository _repository; 
    private string _firstName; 
    private string _lastName; 
    private string _address; 
    private Customer _currentCustomer; 

    public Presenter(Repository repository) 
    { 
     _repository = repository; 
    } 

    public string FirstName 
    { 
     get { return _firstName; } 
     set 
     { 
      if (_firstName == value) return; 
      _firstName = value; 
      OnPropertyChanged(); 
     } 
    } 

    public string LastName 
    { 
     get { return _lastName; } 
     set 
     { 
      if (_lastName == value) return; 
      _lastName = value; 
      OnPropertyChanged(); 
     } 
    } 

    public string Address 
    { 
     get { return _address; } 
     set 
     { 
      if (_address == value) return; 
      _address = value; 
      OnPropertyChanged(); 
     } 
    } 

    public IEnumerable GetCustomers() 
    { 
     return _repository.GetAllCustomers(); 
    } 

    public void Init() 
    { 
     var result = _repository.GetAllCustomers(); 
     SetSelectedCustomer(result[0].Id); 
    } 

    public void SetSelectedCustomer(int customerId) 
    { 
     var customer = _repository.GetCustomerById(customerId); 
     FirstName = customer.FirstName; 
     LastName = customer.LastName; 
     Address = customer.Address; 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 
    { 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

Dies ist, was die Ansicht wie folgt aussieht:

public partial class Form1 : Form 
{ 
    private IPresenter _presenter; 
    private bool _initialized; 

    public Form1(IPresenter presenter) 
    { 
     InitializeComponent();   
     _presenter = presenter; 
     _presenter.Init(); 
     SetComboBoxData(_presenter.GetCustomers()); 
     _initialized = true; 
    } 

    public void SetComboBoxData(IEnumerable data) 
    { 
     comboBox1.DataSource = data; 
     comboBox1.ValueMember = "Id"; 
     comboBox1.DisplayMember = "FirstName"; 
    } 

    private void comboBox1_SelectedIndexChanged(object sender, System.EventArgs e) 
    { 
     if (!_initialized) return; 
     _presenter.SetSelectedCustomer((int)comboBox1.SelectedValue); 
    } 

    private void Form1_Load(object sender, System.EventArgs e) 
    { 
     textBox1.DataBindings.Add(new Binding("Text", _presenter, nameof(_presenter.FirstName))); 
     textBox2.DataBindings.Add(new Binding("Text", _presenter, nameof(_presenter.LastName))); 
     textBox3.DataBindings.Add(new Binding("Text", _presenter, nameof(_presenter.Address))); 
    } 
} 

Sie können die ausgewählten CustomerId am Presenter in Ihrem SelectedIndexChanged-Ereignis von Ihrem Combobox eingestellt:

_presenter.SetSelectedCustomer((int)comboBox1.SelectedValue); 

Die SetSelectedCustomer Verfahren in Ihr Presenter (oder der EventHandler für das SelectedCustomerChanged-Ereignis) wählt den Kunden mit der angegebenen CustomerId aus und legt den Vornamen, den Nachnamen und die Adresse fest:

public void SetSelectedCustomer(int customerId) 
{ 
    var customer = _repository.GetCustomerById(customerId); 
    FirstName = customer.FirstName; 
    LastName = customer.LastName; 
    Address = customer.Address; 
} 

sollten Sie tun, um Ihre Bindung für die Textfelder in Form Load:

textBox1.DataBindings.Add(new Binding("Text", _presenter, nameof(_presenter.FirstName))); 
textBox2.DataBindings.Add(new Binding("Text", _presenter, nameof(_presenter.LastName))); 
textBox3.DataBindings.Add(new Binding("Text", _presenter, nameof(_presenter.Address))); 
0

Wenn Sie absolut gegen Ihre Ansicht Zugriff auf Ihre Domain-Objekte ermöglichen - jene das sind Datentabellenzeilen (die, je nachdem, wie schwer sie sind, in manchen Situationen in Ordnung sein könnten) - Sie sollten sich vielleicht mit DTOs beschäftigen. Überprüfen Sie this für eine gute Beschreibung der Überlegungen und einen Ansatz, um es zu tun. Beachten Sie die Erwähnung von Automapper an der Unterseite. Es ist ein großartiges Werkzeug.

EDIT: Ich habe gerade festgestellt, dass Sie an einer Winforms-Lösung interessiert sind, und nicht für ASP.NET. Obwohl der obige Link ASP.NET betrifft, ist die Idee für Winforms-Apps die gleiche.

Verwandte Themen