Some methods about C # plug-in programming and plug-in host data delivery __ programming

Source: Internet
Author: User

Recently did a C # plug-in programming project, involving the WinForm under the plug-in and host data transfer. You want the plug-in to actively pass data to the host instead of the host by running a method to request the data.

The implementation is FORM1 for the host, in the textbox input string can be uploaded into the plug-in.

In addition, you can draw in the plugin through the mouse, click OK to pass the diagram to the host.

Considering the plug-in programming, must involve interface, here I define interface

Namespace Interclass
{public
	delegate void Changedatahandler (list<list<point>> ptlists);  Define delegate public

	interface Inter
	{
		datatransfer datatransfer {get; set;}
		String WhoAmI (DataTransfer DT);  Pass DataTransfer into the plugin at the same time obtain the name of the plugin
		void Action (object sender, EventArgs e);  Plugin entry
		list<list<point>> pointlists {get;}

		Event Changedatahandler Changedata;  Define event
	} public

	class DataTransfer
	{
		private string testdata;

		public string Testdata {get => Testdata; set => Testdata = value;}
	}
}

Refer to data transfer across threads and across forms, and delegates can implement plug-ins to host unsolicited delivery.
Add a dynamic menu to the host plug-in, bind the event to action, and start the plug-in running.

The following is the code for the host form Load plug-in, which contains the actions of the dynamic menu.

Private list<inter> _plugins = new list<inter> (); List of Plug-ins
int _countplugadded = 0;  Plug-in successfully load count
int _countplugadderror = 0;  Plug-in load failure count
datatransfer Maindt;  Instances of data delivery
private void Form1_Load (object sender, EventArgs e) {list<string> List = new list<string> ();
	Maindt = new DataTransfer ();
	Read plugin string path = System.IO.Path.Combine (System.Environment.CurrentDirectory + @ "\dlls\");
	DirectoryInfo dir = new DirectoryInfo (path); fileinfo[] fil = dir.
	GetFiles (); foreach (FileInfo f in fil) {if (F.extension.equals (". dll")) {list.
		ADD (F.fullname); }//Load plugin if (list.
				Count!= 0) {foreach (string tp in list) {try {Inter tempi;
				Assembly ASD = assembly.loadfile (TP); type[] t = ASD.
				GetTypes (); foreach (Type tin in t) {if (tin). GetInterface ("Inter")!= null) {tempi = (inter) activator.createinstance (ASD. GetType (Tin.
						FullName));
						_plugins.add (TEMPI);
						Tempi.changedata + = new Changedatahandler (mydatachanged);
						Create menu ToolStripMenuItem newitem = new ToolStripMenuItem ();
						Newitem.text = Tempi.whoami (Maindt);
						Newitem.click + = tempi.action; ((ToolSTripmenuitem) (Mainmenu.items[1]).
						Dropdownitems.add (NewItem);
						Count cumulative _countplugadded++;
					Break
			A catch (Exception) {_countplugadderror++;
		}} else {ToolStripMenuItem newitem = new ToolStripMenuItem ();
		Newitem.text = "No Plug-In";
		newitem.enabled = false; ((ToolStripMenuItem) (Mainmenu.items[1]).
	Dropdownitems.add (NewItem); MessageBox.Show (_countplugadded.tostring () + "plugin successfully loaded," + _countplugadderror.tostring () + "plug-in failed." ");
}
Then implement the interface in the plugin. First, the plug-in that receives the host data.
host data is passed to the plug-in
The general idea is to pass the DataTransfer instance into the plug-in (which has been passed in when the plug-in is loaded) and then scan the DataTransfer instance through the timer in the plugin. Of course, it can be done through the event, I use the timer here lazy.
Because the interface definition is not associated with a form, the action, which is the entry point of the plug-in program, is instantiated to show the subform.
Namespace Plugin1
{public
	class Class1:inter
	{
		private datatransfer datatransfer;
		Public DataTransfer datatransfer {get => datatransfer; set => datatransfer = value;}

		Public list<list<point>> pointlists => throw new NotImplementedException ()///////Because this plugin does not implement this because it does not pass data to the host. Public

		Event Changedatahandler changedata;//This is not implemented because the plugin does not produce data that is passed to the host. Public

		void Action (object sender, EventArgs e)
		{
			MessageBox.Show ("Plugin1")//test, indicating that the action has started running in Class1.
			formt formt = new FORMT ()//materialized form
			FORMT.SETDT (datatransfer);//setdt is the method defined in FORMT. Used to pass datatransfer into the formt.
			formt.show ()//show the plug-in's subform
		}

		public string WhoAmI (DataTransfer DT)
		{
			datatransfer = new DataTransfer ();
			DataTransfer = dt;//The host's datatransfer incoming plug-in
			return "plugin1";//Returns your name}}
This way, the plugin1 in the host's stand-alone menu can run the plug-in's action method and display the subform.
In the plug-in's form, write:
Namespace Plugin1
{public
	partial class Formt:form
	{
		private int _counter = 0;
		DataTransfer _datatransfer;//incoming data with public

		void Setdt (DataTransfer inputdt) => _datatransfer = Inputdt;

		Public formt ()
		{
			InitializeComponent ();
		}

		The private void Timer1_Tick (object sender, EventArgs e)//is synchronized with the timer scan DataTransfer to achieve the synchronous display of the host data.
		{this
			. Text = "This is a plug-in-created form that is controlled by the plug-in." "+ _counter." ToString ();
			_counter++;
			Monitor.Enter (_datatransfer);
			Label1. Text = _datatransfer.testdata;
			Monitor.pulse (_datatransfer);
			Monitor.Exit (_datatransfer);
		}

		private void Formt_load (object sender, EventArgs e)
		{this
			. Text = "This is a plug-in-created form that is controlled by the plug-in." "+ _counter." ToString ();
			Timer1. Enabled = true;
		}

		private void Button1_Click (object sender, EventArgs e)
		{
			MessageBox.Show (_datatransfer.testdata, " I am a plugin created form ")//by clicking on the button to implement the incoming data.
		}
	}
}
Here I have tried two methods, one is to view through the timer, in addition to the use of button_click implementation of the DataTransfer scan.
Plug-ins actively deliver data to the host
The way the host runs the interface definition does enable you to read the plug-in's information, but it is not good if the plug-in needs to actively deliver the data to the host. Suppose you now need to draw through the mouse in the plugin, and click the button to pass the diagram to the host for display.
Need to define a member in the host
list<list<point>> _mypointlists = new list<list<point>> ();
Record the position of the mouse and line up sequentially. If you lift the mouse, create another new table. Implement the save of the drawing in the plugin.
Implement Interface in plugin:
Namespace Plugin3 {public class Class1:inter {private DataTransfer myDT;
		Public DataTransfer datatransfer {get => mydt; set => myDT = value;}
		Private list<list<point>> _pointlists;

		Public list<list<point>> pointlists {get => _pointlists;}

		public event Changedatahandler Changedata;
			The public void Action (object sender, EventArgs e) {FormE FormE = new FormE ();
			Forme.changepic + = new Changepichandler (picchanged);
		Forme.show ();
			public string WhoAmI (DataTransfer DT) {_pointlists = new list<list<point>> ();
			myDT = DT;
		return "Justforfun";

			private void Picchanged (list<list<point>> ptlists) {_pointlists.clear ();

				foreach (list<point> pl in ptlists) {_pointlists.add (New list<point> ()); foreach (point p in PL) {_pointlists[_pointlists.count-1].
					ADD (new Point ()); _POINTLISTS[_POINTLISTS.COUNT-1][_POINTLISTS[_POINTLISTS.COUNT-1]. Count-1] = p; } changedata?. Invoke (_pointlists);//Execute delegate instance to pass data from Class1 to host}}


As before, the action is also used as the portal, and the Changepic event inside the forme is handled with the Picchanged event in the action.

Because we're drawing inside the forme, not in the Class1, so we're going to define another event, which is changepic to pass the data from the form to the CLASS1. This is the same way as passing data across forms.

Finally executes the Changedata delegate instance. interface defines the Changedata event, in which the host loads the plug-in's code by

Tempi = (inter) activator.createinstance (ASD. GetType (Tin. FullName));
_plugins.add (tempi);
Tempi.changedata + = new Changedatahandler (mydatachanged);

Implements the Changedata event and Mydatachanged event handling. The mydatachanged processing method is defined by the host, and the occurrence of the event is defined by the plug-in, which enables the separation of the host and the plug-in.

In forme, the Changepic event occurs in the Click OK button in addition to the related methods of the drawing

Namespace Plugin3 {public delegate void Changepichandler (list<list<point>> ptlist);
		Define delegate public partial class Forme:form {bool _mouseleftdown = false;
		List<list<point>> _drawpoints;
		int _drawcount = 0;
		int pointnumber = 0;

		Point Mymouseposition;  public event Changepichandler Changepic;
		Define event public FormE () {InitializeComponent (); public void Setform () {} private void Forme_load (object sender, EventArgs e) {} private void Forme_mo

		Usedown (object sender, MouseEventArgs e) {} private void Forme_mouseup (object sender, MouseEventArgs e) {} private void Forme_mousemove (object sender, MouseEventArgs e) {} private void Forme_paint (object sender, Painteve  Ntargs e) {} private void Forme_formclosed (object sender, Formclosedeventargs e) {}//clear private void
			Button1_Click (object sender, EventArgs e) {_drawpoints.clear (); Gc.
			Collect ();
			_drawcount = 0; Pointnumber = 0;
			Text = "points:" + pointnumber.tostring ();
		Invalidate (); } private void Button2_Click (object sender, EventArgs e) {changepic?.
 Invoke (_drawpoints);//Execute delegate instance to pass _drawpoints to Class1 in previous level}}}
The _drawpoints in forme is the list of the current mouse position that is constantly recorded with the mouse movement. A drawing to record in a plug-in form.

The data is then actively delivered to the host through two of events. In this process, only the host is defined by the host through the Changedata event defined by the interface and the handling of the event implemented within the host, and the occurrence of the DataChanged event and other operations are defined by the plug-in, which is the first reason that only receiving the host data does not implement this event. The host can not care whether the plug-in will pass data to the host or when.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.