I don't feel comfortable making changes to code that doesn't have test coverage, so I had to come up with a method to test VB6 ActiveX.
I figured that the ActiveX control was really just a view and I should be able to:
- Create the view Interface in .NET
- Create a Presenter class in .NET that works against the .NET view interface
- Expose the .NET view interface and presenter to COM and implement the view interface on the ActiveX control
Create the View Interface in .NET
The first step was to create a simple view interface for this example. I wanted to have a simple text property and buttons for navigating the documents and the pages within the documents.[ComVisible(true)]
[Guid("CC0FE3CD-BE47-46c4-81E9-08499EDF0633")]
public interface IView
{
string Name { get; set;}
ICommandButton PreviousPageButton { get; }
ICommandButton NextPageButton { get; }
ICommandButton PreviousDocumentButton { get; }
ICommandButton NextDocumentButton { get; }
}
I created another interface for the Command Button object. I did this so I wouldn't have to munge the view interface by including a "Visible", "Enabled" and "Caption" property for each button on the view. The ICommandButton interface looks like this:
[ComVisible(true)]You'll notice the Command button properties are Read Only. The view will return the CommandButton to the Presenter so the Presenter can get/set the properties on the ICommandButton interface. The presenter should not create a Button Control and assign it to the view. That is the responsibility of the view.
[Guid("B5482029-1671-4cc1-8BB7-979E933CF81B")]
public interface ICommandButton
{
string Caption { get; set;}
bool Enabled { get; set;}
bool Visible { get; set;}
}
Create the Presenter class
Next I create a simple presenter class. In order to work with VB 6 I had to do a couple things. First I had to have a default constructor. COM Interop needs a default constructor. Normally with the MVP pattern, you would create a constructor that takes in the IView interface, however VB6 doesn't support parameters in the constructor. Since constructor injection was a solution, I created SetView() method that takes in the view interface.[ComVisible(true)]
[Guid("867E8A4E-6D08-4c06-9B42-F9C8C12CEBDF")]
[ClassInterface(ClassInterfaceType.AutoDual)]
public class Presenter
{
private IView view;
/// <summary>
/// Default constructor for needed for COM Interop
/// </summary>
public Presenter(){}
/// <summary>
/// Use Setter Injection since VB6
/// doesn't allow parameterized constructors.
/// </summary>
/// <param name="view"></param>
public void SetView(IView view)
{
this.view = view;
}
public void Initialize()
{
// Disable all the previous buttons
view.PreviousDocumentButton.Enabled = false;
view.PreviousPageButton.Enabled = false;
}
public void NextPage()
{
view.Name = "Next Page";
}
public void PreviousPage()
{
view.Name = "Previous Page";
}
public void NextDocument()
{
view.Name = "NextDocument";
}
public void PreviousDocument()
{
view.Name = "PreviousDocument";
}
private bool isEnabled = true;
public void ToggleAllButtons()
{
view.NextDocumentButton.Enabled = isEnabled;
view.NextPageButton.Enabled = isEnabled;
view.PreviousDocumentButton.Enabled = isEnabled;
view.PreviousPageButton.Enabled = isEnabled;
//Toggle
isEnabled = !isEnabled;
}
}
Implement the View in VB6
Go dust off your VB 6 we're going in!I had to implement the view and a class that implemented the ICommandButton interface. The view is easy. I have a class that I can implement the IView interface on, but how do I implement and interface on the class that already exists? Wrap it I guess. I created a CommandButtonWrapper Class that implemented the interface from the .NET Assembly. Once again I had to create a method to inject the CommandButton control.
In order to wire all the buttons and controls to the presenter I had to write this code on the Init of the ActiveX control.
The rest of the view is very basic and simple. All button click events are delegated to the presenter and the view properties return or set values on the controls of the view.
All in all this solution looks like it is going to work out. I'm concerned about a couple things, but hopeful that I can start test driving this ActiveX control. Wish me luck!
No comments:
Post a Comment