I have a c# WinForms application in which I have tried to implement the Model View Presenter pattern with Passive View. I create new Views in the Presenter of my 'home screen'. I was wondering if this is bad practice, and if it is, what an alternative might be to resolve this. Also, general improvements are more than welcome.
I have asked a question before about my MVP implementation here (you can check it out if you want more of an idea about how I have implemented the pattern in other parts of my application.
You can find my code below.
View
public partial class HomeScreenView : Form, IHomeScreenView
{
private HomeScreenPresenter _presenter;
// Public members.
public List<string> ExistingAssessments
{
get
{
var assessments = new List<string>();
for(int i = 0; i < recentAssessments.Lines.Count(); i++)
{
assessments.Add(recentAssessments.Lines[i]);
}
return assessments;
}
set
{
recentAssessments.Text = "";
foreach (var assessment in value)
{
recentAssessments.Text = assessment + Environment.NewLine + recentAssessments.Text;
}
}
}
// Public events.
public event EventHandler InitializingAssessments;
public event EventHandler CreatingNewAssessment;
public event EventHandler AddingNewStandard;
public event EventHandler OpeningAssessment;
public event EventHandler GeneratingReport;
// Initialize homescreen. Create an instance of the presenter with a reference the view itsself.
public HomeScreenView(IAssessmentsModel model)
{
InitializeComponent();
_presenter = new HomeScreenPresenter(this, model);
}
// Fires the initializing assessments event.
private void HomeScreenView_Activated(object sender, EventArgs e)
{
InitializingAssessments?.Invoke(this, EventArgs.Empty);
}
// Fires the creating new assessment event.
private void newAssessmentButton_Click(object sender, EventArgs e)
{
CreatingNewAssessment?.Invoke(this, EventArgs.Empty);
}
// Fires the adding new standard event.
private void addStandardButton_Click(object sender, EventArgs e)
{
AddingNewStandard?.Invoke(this, EventArgs.Empty);
}
// Fires the opening assessment event.
private void openAssessmentButton_Click(object sender, EventArgs e)
{
OpeningAssessment?.Invoke(this, EventArgs.Empty);
}
// Fires the generating report event.
private void generateReportButton_Click(object sender, EventArgs e)
{
GeneratingReport?.Invoke(this, EventArgs.Empty);
}
// Displays a message.
public void Message(string message)
{
MessageBox.Show(message);
}
}
Presenter
public class HomeScreenPresenter
{
// Private view and model.
private readonly IHomeScreenView _view;
private IAssessmentsModel _model;
private DetailScreenView detailScreenView;
private StandardScreenView standardScreenView;
private OpenAssessmentScreenView openAssessmentScreenView;
private ReOpenAssessmentScreenView reOpenAssessmentScreenView;
// Initialize the homescreen presenter with an IHomeScreenView and a new assessments model. Subsribe to necessary events.
public HomeScreenPresenter(IHomeScreenView view, IAssessmentsModel model)
{
_view = view;
_model = model;
_view.InitializingAssessments += InitializeAssessments;
_view.CreatingNewAssessment += CreateNewAssessment;
_view.AddingNewStandard += AddNewStandard;
_view.OpeningAssessment += OpenAssessment;
_view.GeneratingReport += GenerateReport;
}
// Fills the list of the view with all existing assessments.
public void InitializeAssessments(object sender, EventArgs e)
{
try
{
var assessments = _model.GetDataList("Assessments", "assessment_name");
if (assessments.Any())
{
HashSet<string> items = new HashSet<string>(assessments);
assessments = items.ToList();
for (int i = 0; i < assessments.Count; i++)
{
assessments[i] = (assessments[i] + ": " + _model.CheckStatus(assessments[i]));
}
_view.ExistingAssessments = assessments;
}
else _view.ExistingAssessments = new List<string>();
}
catch(Exception ex)
{
_view.Message("Error - Initializing assessments has failed.\n"
+ "Error message - " + ex.Message);
}
}
// Creates a detail screen view.
public void CreateNewAssessment(object sender, EventArgs e)
{
if (detailScreenView == null || detailScreenView.IsDisposed)
{
detailScreenView = new DetailScreenView(_model);
}
}
// Creates a standard screen view.
public void AddNewStandard(object sender, EventArgs e)
{
if(standardScreenView == null || standardScreenView.IsDisposed)
{
standardScreenView = new StandardScreenView(new StandardsModel(new DatabaseController()));
}
}
// Creates an open assessment screen view.
public void OpenAssessment(object sender, EventArgs e)
{
if(openAssessmentScreenView == null || openAssessmentScreenView.IsDisposed)
{
openAssessmentScreenView = new OpenAssessmentScreenView(_model);
}
}
// Creates a re open assessment screen view.
public void GenerateReport(object sender, EventArgs e)
{
if(reOpenAssessmentScreenView == null || reOpenAssessmentScreenView.IsDisposed)
{
reOpenAssessmentScreenView = new ReOpenAssessmentScreenView(_model);
}
}
}
HashSet<string> items = new HashSet<string>(assessments);
assessments = items.ToList();
\$\endgroup\$assessments = assessments.Distinct().ToList();
IIRC, it does roughly the same thing under the covers, but it's a lot more obvious what the intent is. \$\endgroup\$