博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

续:DataSource中QueryBuilder的编辑器

Posted on 2009-06-05 19:57  faib  阅读(695)  评论(0编辑  收藏  举报
在前说到DataSource的时候,记得有一个属性QueryBuilder,当前并没有加上编辑器,现在效果如下:

这里共用到两个编辑器:QueryParameterEditor和ModelFieldEditor。
 1 using System;
 2 using System.Reflection;
 3 using System.Drawing.Design;
 4 using System.ComponentModel;
 5 using System.Windows.Forms;
 6 using System.Windows.Forms.Design;
 7 
 8 namespace FaibClass.Data.Controls
 9 {
10     /// <summary>
11     /// 构造器
12     /// </summary>
13     public class QueryParameterEditor : UITypeEditor
14     {
15 
16         public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
17         {
18             //得到数据模型类型
19             Type model = ((DataSource)context.Instance).DataModel;
20             FormQueryParemeter frm = new FormQueryParemeter(model);
21             if (value != null)
22             {
23                 frm.Query = (QueryBuilder)value;
24             }
25             if (frm.ShowDialog() == DialogResult.OK)
26             {
27                 value = frm.Query;
28             }
29             return value;
30         }
31 
32         public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
33         {
34             return UITypeEditorEditStyle.Modal;
35         }
36     }
37 }
38 

  1 using System;
  2 using System.Reflection;
  3 using System.Drawing.Design;
  4 using System.ComponentModel;
  5 using System.Windows.Forms;
  6 using System.Windows.Forms.Design;
  7 
  8 namespace FaibClass.Data.Controls
  9 {
 10 
 11     /// <summary>
 12     /// 数据模型字段编辑器
 13     /// </summary>
 14     public class ModelFieldEditor : UITypeEditor
 15     {
 16         private ModelFieldUI modelUI;
 17 
 18         public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
 19         {
 20             if (provider != null)
 21             {
 22                 //得到数据模型类型
 23                 Type model = ((QueryParameter)context.Instance).modelType;
 24                 IWindowsFormsEditorService edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
 25                 if (edSvc == null)
 26                 {
 27                     return value;
 28                 }
 29                 if (this.modelUI == null)
 30                 {
 31                     this.modelUI = new ModelFieldUI(this, model);
 32                 }
 33                 this.modelUI.Start(edSvc, value);
 34                 edSvc.DropDownControl(this.modelUI);
 35                 value = this.modelUI.Value;
 36                 this.modelUI.End();
 37             }
 38             return value;
 39         }
 40 
 41         /// <summary>
 42         /// 设置编辑器的弹出样式。
 43         /// </summary>
 44         /// <param name="context"></param>
 45         /// <returns></returns>
 46         public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
 47         {
 48             return UITypeEditorEditStyle.DropDown;
 49         }
 50 
 51         /// <summary>
 52         /// 设置编辑器是否可调大小。
 53         /// </summary>
 54         public override bool IsDropDownResizable
 55         {
 56             get
 57             {
 58                 return true;
 59             }
 60         }
 61 
 62         private class ModelFieldUI : TreeView
 63         {
 64             private UITypeEditor editor;
 65             private IWindowsFormsEditorService edSvc;
 66             private object value;
 67             private Type modelType;
 68             private ImageList imglist;
 69 
 70             public ModelFieldUI(UITypeEditor editor, Type type)
 71             {
 72                 this.editor = editor;
 73                 this.modelType = type;
 74                 base.Height = 200;
 75                 base.Width = 200;
 76                 base.BorderStyle = BorderStyle.None;
 77                 base.ShowRootLines = false;
 78                 base.ShowPlusMinus = false;
 79                 base.NodeMouseClick += new TreeNodeMouseClickEventHandler(BaseModelUI_NodeMouseClick);
 80                 imglist = new ImageList();
 81                 imglist.ImageSize = new System.Drawing.Size(1616);
 82                 imglist.ColorDepth = ColorDepth.Depth32Bit;
 83                 //添加图标资源
 84                 imglist.Images.Add(Properties.Resources._const.ToBitmap());
 85 
 86                 base.ImageList = imglist;
 87             }
 88 
 89             void BaseModelUI_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
 90             {
 91                 if (base.SelectedNode == nullreturn;
 92                 value = e.Node.Text;
 93                 this.edSvc.CloseDropDown();
 94             }
 95 
 96             /// <summary>
 97             /// 
 98             /// </summary>
 99             public void End()
100             {
101                 this.edSvc = null;
102                 this.value = null;
103             }
104 
105             /// <summary>
106             /// 
107             /// </summary>
108             /// <param name="edSvc"></param>
109             /// <param name="value"></param>
110             public void Start(IWindowsFormsEditorService edSvc, object value)
111             {
112                 this.edSvc = edSvc;
113                 this.value = value;
114 
115                 this.Nodes.Clear();
116                 if (modelType != null)
117                 {
118                     //取出模型类中静态的字段常量
119                     foreach(FieldInfo finfo in modelType.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance))
120                     {
121                         if (finfo.Name == "_TableName" || finfo.Name == "_PrimaryKey"continue;
122                         string value1 = finfo.GetValue(null).ToString();
123                         TreeNode node = new TreeNode(value1);
124                         node.ImageIndex = 0;
125                         if (value != null)
126                         {
127                             if (value.ToString() == value1)
128                             {
129                                 base.SelectedNode = node;
130                             }
131                         }
132                         base.Nodes.Add(node);
133                     }
134                 }
135             }
136 
137             /// <summary>
138             /// 当前选定的类名称
139             /// </summary>
140             public object Value
141             {
142                 get
143                 {
144                     return this.value;
145                 }
146             }
147         }
148     }
149 }
150 

这里还有一个窗体,就是一开始显示的那个图形界面窗体:
  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Drawing;
  6 using System.Text;
  7 using System.Windows.Forms;
  8 
  9 namespace FaibClass.Data.Controls
 10 {
 11     /// <summary>
 12     /// 用于编辑查询参数的窗体
 13     /// </summary>
 14     public partial class FormQueryParemeter : Form
 15     {
 16         private Type modelType;
 17 
 18         public FormQueryParemeter(Type modelType)
 19         {
 20             InitializeComponent();
 21             this.modelType = modelType;
 22         }
 23 
 24         public QueryBuilder Query
 25         {
 26             get 
 27             {
 28                 //返回当前修改的参数集合
 29                 QueryParameterCollection collection = new QueryParameterCollection();
 30                 foreach(ListViewItem item in lvwParameter.Items)
 31                 {
 32                     collection.InternalAdd(item.Tag as QueryParameterBase);
 33                 }
 34                 //QueryParameterCollection转换到QueryBuilder
 35                 return (QueryBuilder)collection;
 36             }
 37             set 
 38             {
 39                 //将参数集合添加到列表中
 40                 QueryParameterCollection collection = value.QueryParameters.Clone();
 41                 foreach(QueryParameterBase p in collection)
 42                 {
 43                     p.modelType = modelType;
 44                     ListViewItem item = MakeItem(p);
 45                     item.Tag = p;
 46                     lvwParameter.Items.Add(item);
 47                 }
 48             }
 49         }
 50 
 51         private ListViewItem MakeItem(QueryParameterBase p)
 52         {
 53             string text = "";
 54             int index = 0;
 55             if (p is QueryParameter)
 56             {
 57                 text = (p as QueryParameter).Field;
 58                 index = 0;
 59             }
 60             //左括号
 61             else if (p is QueryLeftBracket)
 62             {
 63                 text = "(";
 64                 index = 1;
 65             }
 66             //右括号
 67             else if (p is QueryRightBracket)
 68             {
 69                 text = ")";
 70                 index = 2;
 71             }
 72             ListViewItem item = new ListViewItem(text, index);
 73             item.Tag = p;
 74             return item;
 75         }
 76 
 77         /// <summary>
 78         /// 添加一个参数
 79         /// </summary>
 80         /// <param name="sender"></param>
 81         /// <param name="e"></param>
 82         private void btnAdd_Click(object sender, EventArgs e)
 83         {
 84             QueryParameter p = new QueryParameter();
 85             p.modelType = modelType;
 86             ListViewItem item = new ListViewItem("[未定义]"0);
 87             item.Tag = p;
 88             lvwParameter.Items.Add(item);
 89             item.Selected = true;
 90         }
 91 
 92         private void 左括号ToolStripMenuItem_Click(object sender, EventArgs e)
 93         {
 94             QueryLeftBracket p = new QueryLeftBracket();
 95             p.modelType = modelType;
 96             ListViewItem item = new ListViewItem("("1);
 97             item.Tag = p;
 98             lvwParameter.Items.Add(item);
 99             item.Selected = true;
100         }
101 
102         private void 右括号ToolStripMenuItem_Click(object sender, EventArgs e)
103         {
104             QueryRightBracket p = new QueryRightBracket();
105             p.modelType = modelType;
106             ListViewItem item = new ListViewItem(")"2);
107             item.Tag = p;
108             lvwParameter.Items.Add(item);
109             item.Selected = true;
110         }
111 
112         private void pgParemeter_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
113         {
114             if (lvwParameter.SelectedItems[0].Tag is QueryParameter)
115             {
116                 string text = (lvwParameter.SelectedItems[0].Tag as QueryParameter).Field;
117                 lvwParameter.SelectedItems[0].Text = string.IsNullOrEmpty(text) ? "[未定义]" : text;
118             }
119         }
120 
121         private void btnOk_Click(object sender, EventArgs e)
122         {
123             //检查左右括号是否匹配
124             int l = 0, r = 0;
125             foreach (ListViewItem item in lvwParameter.Items)
126             {
127                 if (item.Tag is QueryLeftBracket) l++;
128                 else if (item.Tag is QueryRightBracket) r++;
129             }
130             if (r != l)
131             {
132                 MessageBox.Show("左右括号没有成对出现,不符合Sql语法规则。""提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
133                 return;
134             }
135 
136             DialogResult = DialogResult.OK;
137         }
138 
139         /// <summary>
140         /// 移除
141         /// </summary>
142         /// <param name="sender"></param>
143         /// <param name="e"></param>
144         private void btnRemove_Click(object sender, EventArgs e)
145         {
146             if (lvwParameter.SelectedItems.Count == 0return;
147             lvwParameter.SelectedItems[0].Remove();
148             pgParemeter.SelectedObject = null;
149             lblPg.Text = "{} 的属性:";
150         }
151 
152         private void lvwParameter_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
153         {
154             if (e.IsSelected)
155             {
156                 pgParemeter.SelectedObject = e.Item.Tag;
157                 if (e.Item.Tag is QueryParameter)
158                 {
159                     lblPg.Text = (e.Item.Tag as QueryParameter).Field + " 的属性:";
160                 }
161                 else
162                 {
163                     lblPg.Text = "括号 的属性:";
164                 }
165             }
166         }
167 
168         private void btnOther_Click(object sender, EventArgs e)
169         {
170             contextMenuStrip1.Show(this, btnOther.Left, btnOther.Top + btnOther.Height);
171         }
172 
173         /// <summary>
174         /// 上移
175         /// </summary>
176         /// <param name="sender"></param>
177         /// <param name="e"></param>
178         private void btnUp_Click(object sender, EventArgs e)
179         {
180             if (lvwParameter.SelectedItems.Count == 0)
181                 return;
182             if (lvwParameter.SelectedItems[0].Index == 0)
183                 return;
184             ListViewItem old = (ListViewItem)lvwParameter.SelectedItems[0].Clone();
185             int index = lvwParameter.SelectedItems[0].Index;
186             lvwParameter.Items[index] = (ListViewItem)lvwParameter.Items[index - 1].Clone();
187             lvwParameter.Items[index - 1= old;
188             old.Selected = true;
189         }
190 
191         /// <summary>
192         /// 下移
193         /// </summary>
194         /// <param name="sender"></param>
195         /// <param name="e"></param>
196         private void btnDown_Click(object sender, EventArgs e)
197         {
198             if (lvwParameter.SelectedItems.Count == 0)
199                 return;
200             if (lvwParameter.SelectedItems[0].Index == lvwParameter.SelectedItems.Count - 1)
201                 return;
202             ListViewItem old = (ListViewItem)lvwParameter.SelectedItems[0].Clone();
203             int index = lvwParameter.SelectedItems[0].Index;
204             lvwParameter.Items[index] = (ListViewItem)lvwParameter.Items[index + 1].Clone();
205             lvwParameter.Items[index + 1= old;
206             old.Selected = true;
207         }
208     }
209 }

QueryParameter中的Value是一个object[]类型,所以还提供一个转换器:
 1 using System;
 2 using System.ComponentModel;
 3 using System.Globalization;
 4 using System.Windows.Forms;
 5 
 6 namespace FaibClass.Data.Controls
 7 {
 8     /// <summary>
 9     /// Object数组转换器
10     /// </summary>
11     public class ObjectValueConverter : StringConverter
12     {
13         public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
14         {
15             return true;
16         }
17 
18         public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
19         {
20             return true;
21         }
22 
23         public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
24         {
25             if (value == null)
26                 return "";
27             string ss = "";
28             //将object[]转换为字符串显示,长度跟QueryBuilder中的Append有关
29             //效果为 值1,值2
30             foreach (object v in (object[])value)
31             {
32                 ss += v.ToString() + ",";
33             }
34             return ss.Trim(',');
35         }
36 
37         public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
38         {
39             if (value == null)
40                 return null;
41             if (value.ToString().Length == 0)
42                 return null;
43 
44             //将字符串转换为object[]
45             Type model = ((QueryParameterBase)context.Instance).modelType;
46             Type ptype = model.GetProperty(((QueryParameter)context.Instance).Field).PropertyType;
47             //取模型字段的类型
48             TypeCode tc = Type.GetTypeCode(ptype);
49 
50             string[] ss = value.ToString().Split(',');
51             object[] result = new object[ss.Length];
52             int i = 0;
53             foreach (string v in ss)
54             {
55                 if (v.Length == 0)
56                 {
57                     result[i++= null;
58                 }
59                 else
60                 {
61                     //转换
62                     result[i++= Convert.ChangeType(v.ToString(), tc);
63                 }
64             }
65             return result;
66         }
67     }
68 }
69