MVP Pattern
Depending on the complexity of the user interface it can be worthwhile using an MVP type pattern
Before you can implement this pattern you will need to add the necessary Framework Classes
System.Windows.Forms.MessageBox.Show(ex.Message);
Displaying Modal Form
Add the following code to the Constants.cs file
public struct Structure_RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern bool GetWindowRect(
System.IntPtr hWnd,
ref Constants.Structure_RECT rect);
Add the following code to the Code.cs file
public class Code
{
public static void Method_DisplayForm
{
Constants.Structure_RECT oRect;
System.IntPtr ohandle;
System.Windows.Forms.NativeWindow nativeWindow;
oRect = new Constants.Structure_RECT();
ohandle = Code.Method_HandleGet(Globals.ThisAddIn.Application);
nativeWindow = new System.Windows.Forms.NativeWindow();
nativeWindow.AssignHandle(ohandle);
Constants.GetWindowRect(ohandle, ref oRect);
nativeWindow.ReleaseHandle();
MyForm_Model model = new MyForm_Model();
model.Property_Checkbox = true;
MyForm_View view = new MyForm_View();
view.Property_WindowCenterX = oRect.Left + (oRect.Right - oRect.Left) / 2;
view.Property_WindowCenterY = oRect.Top + (oRect.Bottom - oRect.Top) / 2;
view.Property_Caption = "my new caption";
view.Method_Initialize();
MyForm_Presenter presenter = new MyForm_Presenter(model, view);
view.ShowDialog();
}
}
Add the following assembly reference: "System.Windows.Forms"
Right mouse click on References, in the Solution Explorer window
SS
add "Method_DisplayForm()"
this is the handle for the Microsoft Application window
in an Excel VSTO Add-in this can be accessed from the Application object
MyForm_Model
Creating the Model
Create a new folder in your project called MyForm
Add a class called "MyForm_Model" to the folder MyForm.
Add an Interface above the class.
public interface IMyForm_Model
{
bool Method_Initialize();
}
Replace the Constructor with the following declaration.
The INotifyPropertyChanged interface has a single event called PropertyChanged.
Classes that implement this interface can raise the PropertyChanged event when one of the object properties change.
public class MyForm_Model :
IMyForm_Model,
System.ComponentModel.INotifyPropertyChanged
{
//-----------------------------------------------------------------------
//cannot be renamed, it is part of the INotifyPropertyChanged interface
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
//-----------------------------------------------------------------------
public bool Method_Initialize()
{
return true;
}
//-----------------------------------------------------------------------
private void Method_PropertyChanged(string info)
{
PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(info));
}
}
MyForm_Presenter
Creating the Presenter
Add a class called "MyForm_Presenter" to the MyForm folder.
Make the following changes to this class.
Change the constructor
public class MyForm_Presenter :
MVP.BET_PassiveView<MyForm_Model, MyForm_View>
{
public bool Property_FormCancelled { get; set; }
//-----------------------------------------------------------------------
public MyForm_Presenter(MyForm_Model model, MyForm_View view)
{
bool showform;
base.Initialize(model, view);
showform = model.Method_Initialize();
this.View.Property_Checkbox = this.Model.Property_Checkbox;
this.Property_FormCancelled = false;
if (showform == false)
{
this.View.Method_Close();
}
}
}
Add the following Helper methods
protected override void Method_WireEvents()
{
base.View.Method_RegisterChangeRequestListener(
this.View.GetType().Name,
new System.EventHandler<MVP.BET_EventArgs<string>>
(this.Method_OnEvent));
}
//-----------------------------------------------------------------------
protected override void Method_UnwireEvents()
{
base.View.Method_UnRegisterChangeRequestListener(
this.View.GetType().Name,
new System.EventHandler<MVP.BET_EventArgs<string>>
(this.Method_OnEvent));
}
//-----------------------------------------------------------------------
private void Method_OnEvent(
object Sender,
MVP.BET_EventArgs<string> args)
{
string match = args.RequestedValue.ToString();
enEvents_MyForm enumValue =
(enEvents_MyForm)System.Enum.Parse(typeof(enEvents_MyForm), match);
switch (enumValue)
{
case enEvents_MyForm.OK_Click:
this.Method_Event_OKClick(Sender, args);
break;
case enEvents_MyForm.Cancel_Click:
this.Method_Event_CancelClick(Sender, args);
break;
default:
break;
}
}
//-----------------------------------------------------------------------
public void Method_Event_CancelClick(object sender, System.EventArgs e)
{
this.View.Method_Close();
this.Dispose();
}
//-----------------------------------------------------------------------
public void Method_Event_OKClick(object sender, System.EventArgs e)
{
this.Model.Property_Checkbox = this.View.Property_Checkbox;
this.View.Method_Close();
this.Dispose();
}
MyForm_View
Creating the View
Add a Windows Form "MyForm_View" to the MyForm folder.
This will create a partial class that inherits from the System.Forms.Form class.
Display the Toolbox and add two buttons to this form.
Add a button.
Change button1 to have the name "btnOK" with caption "OK".
Add a button.
Change button2 to have the name "btnCancel" with caption "Cancel".
Add a checkbox
Change checkbox1 to have the name "chbSettings".
Display the code behind this form.
Add the following code to the MyForm_View.cs file.
Add an Enumeration above the partial class for all the different events.
public enum enEvents_MyForm
{
OK_Click,
Cancel_Click
}
Add an Interface under the enumeration called "IMyForm_View".
This defines which members are required.
public interface IMyForm_View
{
int Property_WindowCenterX { get; set; }
int Property_WindowCenterY { get; set; }
string Property_Caption { get; set; }
bool Property_Checkbox { get; set; }
void Method_Close();
void Method_Initialize();
}
Replace the Constructor with the following Partial Class declaration.
public partial class MyForm_View :
System.Windows.Forms.Form,
IMyForm_View
{
private MVP.BET_EventsCollection _eventsCollection = null;
private bool _fireEvents = false;
private bool _formClosing = false;
//-----------------------------------------------------------------------
public MyForm_View()
{
InitializeComponent();
this._eventsCollection = new MVP.BET_EventsCollection(this);
this._fireEvents = true;
this._formClosing = false;
}
}
Add the following Helper methods.
//-----------------------------------------------------------------------
public void Method_RegisterChangeRequestListener<T>(
string propertyName,
System.EventHandler<MVP.BET_EventArgs<T>> eventHandler)
{
this._eventsCollection.Method_AddListener<T>(propertyName, eventHandler);
}
//-----------------------------------------------------------------------
public void Method_UnRegisterChangeRequestListener<T>(
string propertyName,
System.EventHandler<MVP.BET_EventArgs<T>> eventHandler)
{
this._eventsCollection.Method_RemoveListener<T>(propertyName, eventHandler);
}
//-----------------------------------------------------------------------
public void Method_FireChangeRequest(
string propertyName,
string requestedValue)
{
if (this._eventsCollection != null)
{
this._eventsCollection.Method_Fire<string>(propertyName, requestedValue);
}
}
//-----------------------------------------------------------------------
public void Method_Close()
{
if (this._formClosing == false)
{
this._formClosing = true;
}
this.Close();
}
//-----------------------------------------------------------------------
public void Method_Initialize()
{
int center_x = this.Property_WindowCenterX - (int)this.Width / 2;
int center_y = this.Property_WindowCenterY - (int)this.Height / 2;
this.Text = this.Property_Caption;
if ((this.Property_WindowCenterX > 0) && (this.Property_WindowCenterY > 0))
{
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
this.Location = new System.Drawing.Point(center_x, center_y);
}
}
Add the following Properties
public int Property_WindowCenterX { get; set; }
public int Property_WindowCenterY { get; set; }
public string Property_Caption { get; set; }
public bool Property_Checkbox
{
get { return this.chbSetting.Value; }
set { this.chbSetting.Value = value; }
}
Add the following two Event Handlers for the two buttons.
Double click on the buttons to automatically generate the corresponding event handlers.
Add the following code to these event handlers.
private void btnOK_Click(object sender, System.EventArgs e)
{
if ((this._eventsCollection != null) && (this._fireEvents == true))
{
this._eventsCollection.Method_Fire<string>(this.GetType().Name,
enEvents_MyForm.OK_Click.ToString());
}
}
//-----------------------------------------------------------------------
private void btnCancel_Click(object sender, System.EventArgs e)
{
if ((this._eventsCollection != null) && (this._fireEvents == true))
{
this._eventsCollection.Method_Fire<string>(this.GetType().Name,
enEvents_MyForm.Cancel_Click.ToString());
}
}
Add another event handler for the OnFormClosing event.
Display the form and display the Properties window.
Switch to the list of events for the form.
Find the event "FormClosing" and double click on it to generate the corresponding event handler.
Add the following code to this event handler.
protected override void OnFormClosing(System.Windows.Forms.FormClosingEventArgs e)
{
if (this._formClosing == false)
{
this._formClosing = true;
if ((this._eventsCollection != null) && (this._fireEvents == true))
{
this._eventsCollection.Method_Fire<string>(this.GetType().Name,
enEvents_MyForm.Cancel_Click.ToString());
}
}
}
© 2026 Better Solutions Limited. All Rights Reserved. © 2026 Better Solutions Limited TopPrevNext