为控件添加智能标记

  Enterprise Library Step By
Step体系(十二):万分处理应用程序块——进阶篇

在应用系统控件的时候大家常常看见和利用控件的右上角的3个三角型的图标图片 1.gif)
,点击之后弹出3个菜系,标题是“XXXX
职务”,里面提供了无数惠及实用的设置。然而大家和好写的自定义控件中却从未,上面就让自身的UserControl也有那么些效果。

作者:Terrylee

图片 2

一.把要命音讯Logging到数据库

想完毕效益首先要精通效果的名目吧,否则想去谷歌(Google)一下都不通晓要用什么首要字
😀 

在日记和监测应用程序块中,有对象提意见说期待可以把那些新闻Logging到数据库中,在此间介绍一下具体的兑现方式。

本条意义叫做“智能标记 smart tag panel“。

1.开立连锁的数据库环境:

明天以最广大的”在父容器中停靠“成效来演示一下什么样让自定义控件完毕智能标记功能。

我们能够用日志和监测应用程序块自带的SQL语句来创制连锁的数据库环境:

壹 、正所谓”工欲善其事,必先利其器“,首先要引入三个库文件”System.Design“。

创办数据库:

二 、在自定义控件的命名空间下定义1个类,集成ControlDesigner类。(笔者自定义的控件叫做AdSchedule,所以给类起名AdScheduleDesigner)

图片 3CREATE DATABASE [Logging]  ON (NAME = N’Logging’, FILENAME = N’C:\Program Files\Microsoft SQL Server\MSSQL\data\Logging.mdf’ , SIZE = 1, FILEGROWTH = 10%) LOG ON (NAME = N’Logging_log’, FILENAME = N’C:\Program Files\Microsoft SQL Server\MSSQL\data\Logging_log.LDF’ , FILEGROWTH = 10%)

想完毕效益首先要清楚效果的名号吧,不然想去谷歌一下都不亮堂要用什么主要字
😀 那些意义叫做“智能标记 smart tag panel“。
后天以最常见的”在父容器中停靠“效用来演示一下如何让自定义控件完成智能标记功用。
壹 、正所谓”工欲善其事,必先利其器“,首先要引入叁个库文件”System.Design“。
② 、在自定义控件的命名空间下定义一个类,集成ControlDesigner类。(笔者自定义的控件叫做AdSchedule,所以给类起名AdScheduleDesigner)

创建表:

1 public class AdScheduleDesigner : System.Windows.Forms.Design.ControlDesigner

图片 4CREATE TABLE [dbo].[Log] (
图片 5    [LogID] [int] IDENTITY (1, 1) NOT NULL ,
图片 6    [EventID] [int] NULL ,
图片 7    [Category] [nvarchar] (64) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
图片 8    [Priority] [int] NOT NULL ,
图片 9    [Severity] [nvarchar] (32) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
图片 10    [Title] [nvarchar] (256) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
图片 11    [Timestamp] [datetime] NOT NULL ,
图片 12    [MachineName] [nvarchar] (32) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
图片 13    [AppDomainName] [nvarchar] (2048) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
图片 14    [ProcessID] [nvarchar] (256) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
图片 15    [ProcessName] [nvarchar] (2048) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
图片 16    [ThreadName] [nvarchar] (2048) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
图片 17    [Win32ThreadId] [nvarchar] (128) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
图片 18    [Message] [nvarchar] (2048) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
图片 19    [FormattedMessage] [ntext] COLLATE SQL_Latin1_General_CP1_CI_AS NULL 
图片 20) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
图片 21GO
图片 22

 

创制存储过程:

以此类的效应是”增加 Control
的设计格局行为“,类中须求定义二个DesignerActionListCollection类型的性质。

 1图片 23CREATE PROCEDURE WriteLog
 2图片 24(
 3图片 25    @EventID int, 
 4图片 26    @Category nvarchar(64),
 5图片 27    @Priority int, 
 6图片 28    @Severity nvarchar(32), 
 7图片 29    @Title nvarchar(256), 
 8图片 30    @Timestamp datetime,
 9图片 31    @MachineName nvarchar(32), 
10图片 32    @AppDomainName nvarchar(2048),
11图片 33    @ProcessID nvarchar(256),
12图片 34    @ProcessName nvarchar(2048),
13图片 35    @ThreadName nvarchar(2048),
14图片 36    @Win32ThreadId nvarchar(128),
15图片 37    @Message nvarchar(2048),
16图片 38    @FormattedMessage ntext
17图片 39)
18图片 40AS 
19图片 41
20图片 42    INSERT INTO [Log] (
21图片 43        EventID,
22图片 44        Category,
23图片 45        Priority,
24图片 46        Severity,
25图片 47        Title,
26图片 48        [Timestamp],
27图片 49        MachineName,
28图片 50        AppDomainName,
29图片 51        ProcessID,
30图片 52        ProcessName,
31图片 53        ThreadName,
32图片 54        Win32ThreadId,
33图片 55        Message,
34图片 56        FormattedMessage
35图片 57    )
36图片 58    VALUES (
37图片 59        @EventID, 
38图片 60        @Category, 
39图片 61        @Priority, 
40图片 62        @Severity, 
41图片 63        @Title, 
42图片 64        @Timestamp,
43图片 65        @MachineName, 
44图片 66        @AppDomainName,
45图片 67        @ProcessID,
46图片 68        @ProcessName,
47图片 69        @ThreadName,
48图片 70        @Win32ThreadId,
49图片 71        @Message,
50图片 72        @FormattedMessage)
51图片 73GO

 1 private DesignerActionListCollection actionLists;
 2  public override DesignerActionListCollection ActionLists
 3 {
 4    get
 5    {
 6        if (null == actionLists)
 7        {
 8            actionLists = new DesignerActionListCollection();
 9            actionLists.Add(new AdScheduleActionList(this.Component));
10        }
11        return actionLists;
12    }
13 }

该SQL语句默许的不二法门为C:\Program Files\Microsoft Enterprise
Library\src\Logging\Sinks\Database\Scripts,直接运维CreateLoggingDatabase.cmd即可。

 

2.运转配置工具,我们创立贰个日记和监测应用程序块,并建多个Database
Sink,具体的安顿格局在日记和监测应用程序块中讲过了,那里就不重复了,大家看一下它的布局:

三 、再次创下造叁个编纂逻辑程序的类

 图片 74

 1 public class AdScheduleActionList : System.ComponentModel.Design.DesignerActionList
 2 {
 3    private AdSchedule adSchedule;
 4    private DesignerActionUIService designerActionUISvc = null;
 5 
 6    public AdScheduleActionList(IComponent component) : base(component)
 7    {
 8        this.adSchedule = component as AdSchedule;
 9 
10        this.designerActionUISvc =          GetService(typeof(DesignerActionUIService)) as DesignerActionUIService;
11    }
12 }

专注设置StoredProcName为WriteLog,便是我们刚刚创立的仓库储存过程。

 

3.同时再成立多个Category,起名为DataException,并设置它的Sink为Database
Sink。

肆 、在AdScheduleActionList类中重写GetSortedActionItems方法。

4.装置Logging
Handler的LogCategory为大家刚刚创立的DataException,别的的参数临时私下认可。

1 public override DesignerActionItemCollection GetSortedActionItems()
2 {
3     DesignerActionItemCollection items = new DesignerActionItemCollection();
4     items.Add(new DesignerActionMethodItem(this, "ParentComponentStop", "在父容器中停靠"));
5     return items;
6 }

 图片 75

 

5.至此配置达成,在先后中大家不须求做别的变动(那正是公司库的配备驱动的驰念精妙之处^_^)。

中间DesignerActionMethodItem的构造方法有四个参数:

 1图片 76图片 77/**//// <summary>
 2图片 78        /// 日志策略
 3图片 79        /// </summary>
 4图片 80        /// <param name=”sender”></param>
 5图片 81        /// <param name=”e”></param>
 6图片 82        private void btn_Log_Click(object sender, System.EventArgs e)
 7图片 83图片 84        图片 85{
 8图片 86            try
 9图片 87图片 88            图片 89{
10图片 90                Exception ex = new Exception();
11图片 91                throw ex;
12图片 92            }
13图片 93            catch(Exception ex)
14图片 94图片 95            图片 96{
15图片 97                bool Flag = ExceptionPolicy.HandleException(ex,”Log Policy”);
16图片 98
17图片 99                if(Flag)
18图片 100图片 101                图片 102{
19图片 103                    throw;
20图片 104                }
21图片 105            }
22图片 106        }

1、ActionList

填补有些:在品种中要添加对Microsoft.Practices.EnterpriseLibrary.Logging.Sinks.Database.dll的引用

二.可怜的散播机制

② 、要因此面板项调用的章程的名称,此方法是从 DesignerActionList
派生的类中的一个办法,其艺术名分别轻重缓急写。

特其他流传机制有以下两种:

叁 、此项的面板文本。

l        非常活动传播

本条函数写好之后就在AdScheduleActionList类中添加必要调用的措施。

l        在同等层内部,捕获或然再抛出原本卓殊

1 public void ParentComponentStop()
2 {
3     componentLocation = adSchedule.Location;
4     componentSize = adSchedule.Size;
5 
6     adSchedule.Dock = System.Windows.Forms.DockStyle.Fill;
7     adSchedule.Location = new System.Drawing.Point(0, 0);
8 }

l        捕获,包装和抛出包装后的十一分

 

作者们不推荐直接抛出原始非凡,因为恶意的用户能够从系统诊断新闻中获悉应用的详细处境,并从中寻找应用的欠缺。至极应用程序块提供了如若配置的Handler执行后,就时有发生相应的post-handling动作,该动作有如下选项:

伍 、就那样简单,智能标记已经得以用了。

None - 没有重抛分外的动作。

图片 107

NotifyRethrow - 告诉调用程序:Policy推荐应该重抛极度。

 

ThrowNewException - 在有着的Handler执行后,向调用程序抛出最后相当(并不一定是原有的要命)。

点击未来窗口就足以在父容器中停靠,可是难点来了,如何打消停靠呢?


三.分外的格式化

很简单正是修改GetSortedActionItems方法中的DesignerActionItemCollection。

能够格式化任何System.Exception类型的充足

此地大家还索要创设几个变量,在ParentComponentStop函数中赋值用来保存控件停靠前的职位和大小,以便打消的时候回来原来的楷模。

可以用来记录大概突显万分的详细音讯

1 public override DesignerActionItemCollection GetSortedActionItems()
2 {
3    DesignerActionItemCollection items = new DesignerActionItemCollection();
4    if (DockStyle.None == adSchedule.Dock)
5      items.Add(new DesignerActionMethodItem(this, "ParentComponentStop", "在父容器中停靠"));
6    else
7      items.Add(new DesignerActionMethodItem(this, "CancelParentComponentStop", "取消在父容器中停靠"));
8    return items;
9 }

字符型格式化器——TextExceptionFormatter:创立在3个显示器上,日志中或以其余情势表现的,能够展现不行音信的详尽记录

 

XML格式化器——XMLExceptionFormatter:针对2个要命,创设贰个用XML表现形式表现记录,每一个不行的属性,均能够被积存为XML成分。

 1 public void CancelParentComponentStop()
 2 {
 3    if (null == componentLocation)
 4        componentLocation = adSchedule.Location;
 5    if (null == componentSize)
 6        componentSize = adSchedule.Size;
 7 
 8    adSchedule.Dock = DockStyle.None;
 9    adSchedule.Location = componentLocation;
10    adSchedule.Size = componentSize;
11 
12    designerActionUISvc.Refresh(this.Component);
13 }

看一下在Enterprise Library Quick
Start中提供的自定义的ExceptionFormatter,完成了TextExceptionFormatter类:

 

 1图片 108图片 109/**//// <summary>
 2图片 110    /// Summary description for AppTextExceptionFormatter.
 3图片 111    /// </summary>    
 4图片 112    public class AppTextExceptionFormatter : TextExceptionFormatter
 5图片 113图片 114    图片 115{
 6图片 116        public AppTextExceptionFormatter(TextWriter writer, Exception exception)
 7图片 117            : base (writer, exception) 
 8图片 118图片 119            图片 120{
 9图片 121            }
10图片 122        
11图片 123        protected override void WriteDescription() 
12图片 124图片 125        图片 126{
13图片 127            // An exception of type {0} occurred and was caught.
14图片 128            string line = String.Format(“An exception of type {0} occurred and was caught.”, base.Exception.GetType().FullName);
15图片 129            this.Writer.WriteLine(line);
16图片 130        }
17图片 131
18图片 132        protected override void WriteExceptionType(Type exceptionType) 
19图片 133图片 134        图片 135{
20图片 136            base.Indent();
21图片 137            base.Writer.WriteLine(“Type : {0}”, exceptionType.FullName);
22图片 138        }
23图片 139
24图片 140        public override void Format() 
25图片 141图片 142        图片 143{
26图片 144            //this.Writer.WriteLine(“Message : {0}”, message);
27图片 145            this.WriteDescription();
28图片 146            //this.WriteExceptionType(base.Exception.GetType());
29图片 147            base.WriteMessage(base.Exception.Message);
30图片 148        }
31图片 149
32图片 150    }

还未曾完,点击之后干什么仍然“在父容器中停靠”?文字没有变动呢?

四.开立自定义的那么些处理器

还记得designerActionUISvc那些变量吗?他用来缓存DesignerActionUIService,以贯彻DesigneractionList刷新作用。

那些处理应用程序块允许你包装并动用你自身的不等业务处理流程,例如在岁月记下系统中填入一个事件,利用业务规范开始展览打包和代表,利用别的的记录系统进行记录(相比较常用的有Log4net,前段时间深渊野鱼介绍的,还没用过^_^),那种灵活的可配置性,将允许你在不相同的十一分类型及其策略中灵活的布局。

在ParentComponentStop函数最终加上那句话

能够通过完结ExceptionHandler抽象类,来创制定制的Handler

1 designerActionUISvc.Refresh(this.Component);

1图片 151public abstract class ExceptionHandler : ConfigurationProvider, IExceptionHandler

 

该抽象类继承ConfigurationProvider类,并达成IExceptionHandler接口。ConfigurationProvider抽象类达成了IConfigurationProvider接口,用来读取配置数据。

近日就水到渠成了,喝杯咖啡自个儿欣赏一下吗。

1图片 152public abstract class ConfigurationProvider : IConfigurationProvider

 

采取支持体系化的数据类型作为配置参数,还有要留心数据类型的大致,制止“Exception Handling Exceptions”

那只是个简单的使用,简单的文字链接形式实现调用函数,其实在智能标记中得以兑现无数意义。

看一下在Enterprise Library Quick
Start中提供了定制Handler的达成:

大家能够参见一下MSDN,给DesignerActionItemCollection传入差别门类的值就会兑现越多的操作。

 1图片 153图片 154/**//// <summary>
 2图片 155  /// Summary description for GlobalPolicyExceptionHandler.
 3图片 156  /// </summary>
 4图片 157  public class AppMessageExceptionHandler : ExceptionHandler
 5图片 158图片 159  图片 160{
 6图片 161    public AppMessageExceptionHandler()
 7图片 162图片 163    图片 164{
 8图片 165    }
 9图片 166
10图片 167    public override void Initialize(ConfigurationView configurationView)
11图片 168图片 169    图片 170{
12图片 171    }
13图片 172
14图片 173    public override Exception HandleException(Exception exception, string policyName, Guid correlationID) 
15图片 174图片 175    图片 176{
16图片 177      DialogResult result = this.ShowThreadExceptionDialog(exception);
17图片 178
18图片 179      // Exits the program when the user clicks Abort.
19图片 180      if (result == DialogResult.Abort) 
20图片 181        Application.Exit();
21图片 182
22图片 183      return exception;
23图片 184    }
24图片 185
25图片 186    // Creates the error message and displays it.
26图片 187    private DialogResult ShowThreadExceptionDialog(Exception e) 
27图片 188图片 189    图片 190{
28图片 191      string errorMsg = e.Message + Environment.NewLine + Environment.NewLine;
29图片 192
30图片 193      return MessageBox.Show(errorMsg, “Application Error”, MessageBoxButtons.OK, MessageBoxIcon.Stop);
31图片 194    }
32图片 195  }

图片 196

甘休语:卓殊处理应用程序块的进阶篇就写到那里了。

下载源代码

 

参考MSDN文献:

彩排:向 Windows
窗体组件添加智能标记
.aspx)

 

怎么着:向 Windows
窗体组件附加智能标记
.aspx)

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图