Previously promised to Winform IDE,WPF customer Service Program development further decomposition records, I am sorry has not been too much time to carefully comb.
This blog extracts the implementation of a common feature of both applications, namely, the control of menus and toolbars in a plug-in application.
For complex application development, we may decompose, modularize, and plug-in the functions of the program, so how to provide a unified menu, toolbar registration, update, and destroy mechanism in the application host. And how do you do the UI-independent, complete decoupling?
See two examples:
Winform-based plug-in applications: http://www.cnblogs.com/sheng_chao/p/4387249.html
This is a Winform-based IDE program, and the main menu and toolbars vary depending on the loaded module and the currently activated form, and the state of the Menu and toolbar button differs depending on the data or behavior in the current activation window.
The toolbar portion of the yellow background in the figure is specific to the form designer, similar to the specific menu item that appears when you select a graphic or table in a new version of Word. Whenever you do different things in the form designer, the items in the toolbar will appear in different states.
WPF-based plug-in applications: http://www.cnblogs.com/sheng_chao/p/4548146.html
This is a common desktop application based on WPF, and depending on which modules are currently loaded, the main menu above shows different items. This example is simple, although the main menu is loaded according to the plugin, but there is no state change after loading.
In general, when the host program loads the plug-in, it reads the information associated with the plug-in based on some pre-configured plug-in information, such as a configuration file.
In the past, many applications, through the configuration of the menu and toolbar configuration file to declare to the host, the advantages of this way is simple, easy to develop, almost no difficulty, the disadvantage is that the menu and toolbar can be almost static configuration, if you need to dynamically update, revoke the menu or toolbar when the program runs, It is not the best choice to realize this idea.
The second way I often see it is that developers simply throw a menu or toolbar from the UI layer to the plugin, and the host only provides a basic UI container to host the UI objects provided by the plug-in, such as the entire UserControl. This way if you must say that there are any advantages, that is to develop a comparative simple , the lack of more than the first way, the host program lost the absolute control of the plug-in, the plug-in program can provide their own different forms of the UI, so that the main program related functions presented, control , is no longer unified, second, the main program becomes very vulnerable, the host program is not valid, completely Handle from these UI exceptions, also cannot monitor, control the method calls in these UI, such as the time-out method call display waiting UI, or forcibly abort, cannot dispatch these method calls. The plugin provides a completely uncontrolled UI when the host program modifies the rendering of menus and toolbars as a result of an upgrade, or needs to support a skin-changing function. In addition, this approach can lead to a lot of repetitive work, wasting the developer productivity, because most of the menu, toolbar project rendering, are similar, have a certain regularity, can be handled in an automated manner.
The third way of thinking is to be provided by the host program interface for plug-ins to invoke, so that the plug-in can be dynamic control of menus and toolbars, the benefits of this does not exist in the above method Two problems, the second is to solve the method one, Dynamic control that cannot be achieved by static loading.
There are many ways to do this, and in the past we have seen a scenario that provides a series of methods for plug-in invocation, which has a significant drawback, which is complexity, which complicates the code and complicates the logic. A range of registrations, updates, revocation methods, and many different parameter overloads are required to implement the appropriate functionality. When there are new requirements in development, such as binding permissions on menus and toolbar items, a series of interface modifications or parameter modifications are required.
In the above two examples, the menu and toolbar resources, through a similar URI, Uniform Resource identifiers to control, the maximum amount of plug-in development workload to minimize, the most easy, so that the intern level of developers, through 10 minutes of explanation, you can calmly grasp.
Implementation results:
Private voidinitializenavigation () {_navigationservice.register ("mainmenu://session[text= ' Session ']/session/"); _navigationservice.register ("mainmenu://session/session/contact[text= ' contacts ']", NewAction (() ={contactview.showinstance ();})); _navigationservice.register ("mainmenu://setup[text= ' Settings ']/contact/"); _navigationservice.register ("mainmenu://setup/contact/customercategory[text= ' business type ', authorizekey= ' managecustomercategory ']", NewAction (() ={customercategorylistview.showinstance ();})); _navigationservice.register ("mainmenu://setup/contact/customerimportentlevel[text= ' Important level ', authorizekey= ' managecustomerimportentlevel '] ", NewAction (() ={customerimportentlevellistview.showinstance ();})); }
It is believed that a slightly experienced developer can understand the meaning of this code without explanation.
After the plug-in obtains the Inavigationservice (_navigationservice) interface provided by the host, it can implement dynamic registration of a menu or toolbar item by simply invoking the Register method, passing in the URI and related parameters.
The definition of the Inavigationservice interface is simple:
Public Interface Inavigationservice { void Register (string path); void Register (string path, action action); void Register (Navigationcodon codon); void Update (string path);
From the literal meaning can fully understand, avoids the traditional large section method to provide the related function, the core lies in the parameter path, the Uniform Resource identifier.
The Protocol section can be implemented according to the functions provided by the host, such as:
MainMenu: Main Menu; Toolbar: toolbar: QuickStart: Quick Start tool, etc.
Take MainMenu as an example:
Path points indicate the "hierarchy" of the current target menu, in this example, the first part of the path is Setup, which is implemented as the top-level menu in the example above Winform application, whereas for the second WPF example, the Ribbon-style menu is implemented as the tab page, and the second part of the path The contact is implemented as a level two menu, or ignored, implemented as a Group under the Tab page in the Ribbon menu, and the third part customercategory the specific menu item "Business Type".
The third part of the path customercategory only specifies the Name of the menu item, and the other properties are specified by the attribute syntax enclosed in brackets, namely: text= ' business type ', authorizekey= ' managecustomercategory '.
In a concrete implementation, the properties available in attribute syntax are specially handled, allowing for framework-independent, UI-independent, dynamic scaling. It is very easy to extend the properties available in the property syntax. With the realization of the inavigationservice itself, is completely decoupled, irrelevant.
It means that with the development of the application and the change of requirements, when new functions need to correspond, it is only necessary to indicate the new attribute names and implement their functions in a specific location, and the framework is irrelevant to inavigationservice.
All of the new attributes, or even the removal of the original property, can not affect any existing code, the new property implementation does not affect the original code, and the original code attributes of the property if need to cancel, cancel the relevant corresponding, inavigationservice in the parsing can not find the corresponding implementation, Can be ignored directly after logging, such as the 1.0 version of the host to support the color of the specified menu, to 2.0 is not supported, the original code to work at 1.0, is not affected at all, just the designation to 2.0 becomes invalid, thus achieving good backward compatibility.
Inavigationservice also provides the Update method for updating the state of a menu or toolbar item, while using attribute syntax directly in path, such as:
_navigationservice.update ("mainmenu://setup/contact/customercategory[enable= ' False ']" ,
In addition, the Inavigationservice interface supports a more complex parameter object Navigationcodon
Public classNavigationcodon { PublicNavigationpath Path {Get;Private Set; } PublicAction Action {Get;Set; } Publicfunc<BOOL> Isenablefunc {Get;Set; } PublicFunc<visibility> Visibilityfunc {Get;Set; } PublicNavigationcodon (stringpath) { This. Path =NewNavigationpath (path); } }
Fine-grained control of menus and toolbar items in more complex scenarios, such as the Winform IDE environment above.
By resource-based menus and toolbar items, not only does the full decoupling between the host and the plug-in, but also provides a way for the plug-in to decouple the menu toolbar, and when the plugin realizes its own business, it does not need to get a strong reference to the menu and toolbar items, through Inavigationservice Can be related to the operation.
At this point, welcome criticism. :)
a little feeling: many development work, looks simple, want to do well but not easy, for example, the problem described in this article, I have experienced a large software project, in the various plug-in Ribbon menu control, repeatedly, produced a lot of problems, wasting a lot of manpower and time. More than half of the time in serious and menu rivalry (CAD software, complex functions, interface complexity). But these problems can be easily avoided, the development team's own understanding of the problem is not deep enough, the leadership of the lack of attention is also a big factor for the software development work is not enough to understand, the idea stuck in the drag control, painting interface, reluctant to put more manpower, financial support for the team, resulting in the team members, constantly postponed. but can not find the crux of the problem, I think if the team on the development of the details of attention, as long as a conference room closed door to find ways, there are many detours is not necessary to go. Therefore, the best way to meet repeated problems is to stop and re-examine.
Small ads
Bloggers are paying attention to the relevant senior positions in Nanjing
Jiangsu Telecom Technical Manager No. 10,000th, currently a foreign-funded company team Leader
Biography:http://121.40.198.87:8010/
Use. NET WinForm to develop a WYSIWYG IDE development environment that allows you to build your application without writing code directly:
Http://www.cnblogs.com/sheng_chao/p/4387249.html
Development of online customer service system using wpf+ ASP (one):
Http://www.cnblogs.com/sheng_chao/p/4548146.html
Implement full decoupling and state control of menus, toolbar buttons in plug-in applications