Proper Form Application Design
I'm creating a WinForm application in C# and one of its functions is displaying tex开发者_如何转开发t in text boxes. I'm coding the logic for querying a database in a separate class and am unable to access the text box element in the class I'm creating (I'm getting a "name" does not exist in the current context error). Do I put all of my form logic into my Form1.cs file?
You should try to keep your display logic separate from the rest of the application - the simplest thing to do is have the form class handle getting/setting form values. This means your data access component will query the database and the form will have to map the output to something that can be displayed e.g.
public class Form1 : Form
{
public DataAccess Db { get; set; }
public void UpdateSomething()
{
this.textbox.Text = this.Db.GetSomeDatabaseValue();
}
}
No keep Business logical apart from UI logic. You should raise an event in the Business class and catch it in the UI form. From there display it.
If they are not try setting the modifiers in properties to public or internal.
Edit- edited to fit answer format
If you want to access the TextBox in another class change the access modifier as
public or Internal (If it is in the same assembly)
. Default it will be private
Better you can pass the value to the business logic layer.Not the entire control,would not be good always.
B.I
is to do all the business so the value of text box is enough.
Have you looked at the backgroundworker? With this, you can run things asynchronously when you click a button on your form. All of your updating things on your form would be done on your form itself. Your other code (that you were having trouble accessing Form1 from) would 'report progress.' When progress is reported, you can send any object that you want to Form1 and then in an event handler on the form you can take information from that object and update the view. You would use this, for example, to update a progress bar while keeping the UI responsive.
We are currently doing an application with a MVP pattern in winforms. We are using the bindings in winforms so the UI will update when the data does. Our forms use BindingSources and BindingLists. We bind the main BindingSource to our presenter class.
Example of Form codebehind
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SomeNameSpace.Utilities.UI;
using SomeNameSpace.Utilities.Validation;
namespace Management.UI
{
public partial class ManualControl : UserControl, IManualRaffleView
{
private ManualPresenter _presenter;
public ManualControl()
{
InitializeComponent();
}
[Browsable(false)]
public ManualPresenter Presenter
{
get
{
return _presenter;
}
set
{
_presenter = value;
if(_presenter != null)
{
_manualPresenterBindingSource.DataSource = _presenter;
_ListBindingSource.DataSource = _presenter;
_ListBindingSource.DataMember = "Something";
_KindListBindingSource.DataSource = _presenter;
_KindListBindingSource.DataMember = "SomethingElse";
_presenter.CloseView += new Action(CloseMe);
_presenter.VerifyingCancel += new Func<bool>(VerifyingCancel);
_presenter.Showing += new Action(ShowMe);
_presenter.Synchronizer = this;
}
}
}
void CloseMe()
{
this.Enabled = false;
}
private void ManualRaffleForm_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = false;
}
private void ShowMe()
{
this.Enabled = true;
}
bool VerifyingCancel()
{
return MessageBox.Show("Cancel?", Notifier.ApplicationName,
MessageBoxButtons.YesNo, MessageBoxIcon.Question,
MessageBoxDefaultButton.Button2) == DialogResult.Yes;
}
private void _cancelButton_Click(object sender, EventArgs e)
{
Presenter.HandleCancel();
}
private void _initiateButton_Click(object sender, EventArgs e)
{
Presenter.HandleInitiate();
}
private void _saveButton_Click(object sender, EventArgs e)
{
if(Presenter.Error == true.ToString())
Presenter.HandleDone();
else
_manualPresenterBindingSource.ResetBindings(false);
}
}
}
Then our Presenter implements INotifyPropertyChanged and may look something like this
namespace SomeCompany.UI
{
public class ManualPresenter : INotifyPropertyChanged, IDataErrorInfo
{
#region Fields
//fields
#endregion Fields
public string SomeFormField
{ get{ return _someFormField;}
set{
if(_someFormField != value)
{
_someFormField = value;
//Update Model if Needed
_model.SomeFormField = _someFormField;
NotifyCHanged("SomeFormField");
}
}
}
The form text boxes will bind to the properties in the presenter and any listboxes or combo boxes will bind to BindingLists. We then use Linq to Sql for our models. There is very little logic in the Forms. Mostly just a little that is necessary for validation.
精彩评论