MVP Winforms 和文本框组合框值
MVP Winforms and textbox combobox values
我有一个以列表作为数据源的组合框。此列表包含对象(客户)及其属性(名称、地址...)。
当我 select 组合框的一个项目时,我想将信息(地址、邮政编码...)传递到我表单上的一些文本框。
在我的测试 1tier 应用程序中,这工作正常。
但是我正在处理的主要应用程序是基于 MVP(我自己接触过)。我面临的问题是铸造。由于我的视图不知道我的模型,因此不应允许我使用(客户)。 string address = ((Customers)comboBox1.SelectedItem).CustomerAddress;
1层测试代码:
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();
}
}
我已经研究了几天了,但还没有成功。我希望有人能给我正确的方向。
实际应用代码:
查看:
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";
}
主持人:
public List<tbl_customer> getCustomers()
{
using (var customers = new DBCrownfishEntities())
{
var customer = from c in customers.tbl_customer
select c;
return customer.ToList();
}
}
如果您绝对反对让您的视图访问您的域对象——那些代表数据 table 行的对象(在某些情况下可能没问题,具体取决于它们的重量)——您可能想研究使用 DTO。检查底部的 this out for a good description of considerations and one approach to doing it. Note the mention of Automapper。这是一个很棒的工具。
编辑:我刚刚意识到您对 Winforms 解决方案感兴趣,而不是 ASP.NET。虽然上面的 link 涉及 ASP.NET,但 Winforms 应用程序的想法是相同的。
这只是实现它的一种方法。您的 MVP 模式可能看起来不同。
在这个实现中,View 知道 Presenter。关于MVP的更多信息你可以看看here
您可以将 Presenter 用作客户的包装器:
public interface IPresenter
{
void Init();
void SetSelectedCustomer(int customerId);
IEnumerable GetCustomers();
string FirstName { get; set; }
string LastName { get; set; }
string Address { get; set; }
}
Presenter 必须实现 INotify属性Changed(并在 属性 setter 中调用 On属性Changed)。
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));
}
}
这是视图的样子:
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)));
}
}
您可以在组合框中的 SelectedIndexChanged 事件中的 Presenter 中设置选定的 CustomerId:
_presenter.SetSelectedCustomer((int)comboBox1.SelectedValue);
Presenter 中的 SetSelectedCustomer 方法(或 SelectedCustomerChanged 事件的事件处理程序)选择具有给定 CustomerId 的客户并设置 FirstName、LastName 和 Address:
public void SetSelectedCustomer(int customerId)
{
var customer = _repository.GetCustomerById(customerId);
FirstName = customer.FirstName;
LastName = customer.LastName;
Address = customer.Address;
}
您应该对 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)));
我有一个以列表作为数据源的组合框。此列表包含对象(客户)及其属性(名称、地址...)。
当我 select 组合框的一个项目时,我想将信息(地址、邮政编码...)传递到我表单上的一些文本框。
在我的测试 1tier 应用程序中,这工作正常。
但是我正在处理的主要应用程序是基于 MVP(我自己接触过)。我面临的问题是铸造。由于我的视图不知道我的模型,因此不应允许我使用(客户)。 string address = ((Customers)comboBox1.SelectedItem).CustomerAddress;
1层测试代码:
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();
}
}
我已经研究了几天了,但还没有成功。我希望有人能给我正确的方向。
实际应用代码:
查看:
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";
}
主持人:
public List<tbl_customer> getCustomers()
{
using (var customers = new DBCrownfishEntities())
{
var customer = from c in customers.tbl_customer
select c;
return customer.ToList();
}
}
如果您绝对反对让您的视图访问您的域对象——那些代表数据 table 行的对象(在某些情况下可能没问题,具体取决于它们的重量)——您可能想研究使用 DTO。检查底部的 this out for a good description of considerations and one approach to doing it. Note the mention of Automapper。这是一个很棒的工具。
编辑:我刚刚意识到您对 Winforms 解决方案感兴趣,而不是 ASP.NET。虽然上面的 link 涉及 ASP.NET,但 Winforms 应用程序的想法是相同的。
这只是实现它的一种方法。您的 MVP 模式可能看起来不同。 在这个实现中,View 知道 Presenter。关于MVP的更多信息你可以看看here
您可以将 Presenter 用作客户的包装器:
public interface IPresenter
{
void Init();
void SetSelectedCustomer(int customerId);
IEnumerable GetCustomers();
string FirstName { get; set; }
string LastName { get; set; }
string Address { get; set; }
}
Presenter 必须实现 INotify属性Changed(并在 属性 setter 中调用 On属性Changed)。
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));
}
}
这是视图的样子:
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)));
}
}
您可以在组合框中的 SelectedIndexChanged 事件中的 Presenter 中设置选定的 CustomerId:
_presenter.SetSelectedCustomer((int)comboBox1.SelectedValue);
Presenter 中的 SetSelectedCustomer 方法(或 SelectedCustomerChanged 事件的事件处理程序)选择具有给定 CustomerId 的客户并设置 FirstName、LastName 和 Address:
public void SetSelectedCustomer(int customerId)
{
var customer = _repository.GetCustomerById(customerId);
FirstName = customer.FirstName;
LastName = customer.LastName;
Address = customer.Address;
}
您应该对 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)));