zoukankan      html  css  js  c++  java
  • 为SSIS编写自定义数据流组件之进阶篇:自定义属性的下拉式编辑器

    之前的一篇文章中,我们讲解到了,如果一个自定义属性是可选值,我们可能更希望用下拉列表的方式让用户选择,而不是弹出一个对话框。

    http://www.cnblogs.com/chenxizhang/archive/2009/06/21/1507686.html

    上面这一篇讲解的是如何通过枚举类型的方式实现简单的下拉列表。很显然的一个问题是,枚举的个数是固定的,而且是有限的。

    那么有没有办法让我们的列表更加灵活呢?例如动态生成一个列表。答案是:可以的。这就是本篇文章探讨的问题

    我们首先来看一下具体的效果

    image

    还是我们那个“文件夹数据源”的组件,它的Folder属性,现在点击下拉框之后,能够自动地枚举出来C盘下面的所有子目录,以供选择。这当然会更加好一些。

    下面来看看我们是怎么实现的

    1. 创建一个单独的UITypeEditor

        public class MyTypeUIDropDownEditor : System.Drawing.Design.UITypeEditor {
     
            IWindowsFormsEditorService editorService = null;
     
            public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, 
                IServiceProvider provider, object value)
            {
                if (context != null && context.Instance != null && provider != null)
                {
                    editorService = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
                    if (editorService != null)
                    {
                        string current = "没有选择文件夹";
                        if (value != null)//这个value其实就是当前用户已经选择好的值
                            current = value.ToString();
                        MyTypeUIDropDownControl ctrl = new MyTypeUIDropDownControl(current);
     
                        ctrl.ValueChanged += new MyTypeUIDropDownControl.ValueChangedHander(ctrl_ValueChanged);
                        //添加这个事件的目的是在值发生变化的时候,自动把列表关闭掉
                        //这是一个自定义事件
     
     
                        editorService.DropDownControl(ctrl);
                        
                        value = ctrl.Folder;
                        return value;
                    }
                }
                return value;
            }
     
            void ctrl_ValueChanged()
            {
                editorService.CloseDropDown();
            }
     
            public override UITypeEditorEditStyle GetEditStyle(
                System.ComponentModel.ITypeDescriptorContext context)
            {
                return UITypeEditorEditStyle.DropDown;
            }
     
            public override bool IsDropDownResizable
            {
                get
                {
                    return true;
                }
            }
     
            
        }

    2. 我们在这个编辑器中,需要用到一个用户控件。直接继承UserControl

    image

    这个控件上,有一个ListBox,它的Dock属性设置为Fill

    image

    控件的代码大致如下

    using System;
    using System.Windows.Forms;
    using System.IO;
     
    namespace MyDataFlowComponentSample
    {
        public partial class MyTypeUIDropDownControl : UserControl
        {
            public MyTypeUIDropDownControl()
            {
                InitializeComponent();
     
                foreach (var item in Directory.GetDirectories("c:\\"))
                {
                    lstFolder.Items.Add(item);
                }
            }
     
            public MyTypeUIDropDownControl(string current)
                : this()
            {
                lstFolder.SelectedValue = current;
            }
     
     
            private string folder;
            public string Folder
            {
                get { return folder; }
                set { folder = value; }
            }
            private void lstFile_SelectedIndexChanged(object sender, EventArgs e)
            {
                folder = lstFolder.SelectedItem.ToString();
                if (ValueChanged != null)
                    ValueChanged();
            }
     
     
            public delegate void ValueChangedHander();
            public event ValueChangedHander ValueChanged;
        }
    }

    3. 将我们的Editor与自定义属性进行关联

    folder.UITypeEditor = typeof(MyTypeUIDropDownEditor).AssemblyQualifiedName;

    4. 生成项目,部署,测试。

    如果不出意外,你就可以看到本文开篇出的那个效果

    5. 更多联想。只要你愿意,你当然可以在那个UserControl中做更多的事情,让你的编辑器下拉列表更加酷。看看下面这样的效果

    image

    using System;
    using System.Windows.Forms;
    using System.IO;
    using System.Drawing;
    
    namespace MyDataFlowComponentSample
    {
        public partial class DropDownControl : UserControl
        {
            public DropDownControl()
            {
                InitializeComponent();
            }
            protected override void OnLoad(EventArgs e)
            {
                int i = 0;
                Random rnd = new Random();
                foreach (var item in Directory.GetDirectories("c:\\"))
                {
                    Button bt = new Button();
                    bt.Width = this.Width - 40;
                    bt.Height = 40;
                    bt.BackColor = Color.FromArgb(rnd.Next(255), rnd.Next(255), rnd.Next(255));//随机给一个颜色
                    bt.Text = item;
    
                    bt.Left = 0;
                    bt.Top = i * 40;
                    i++;
                    bt.Click += new EventHandler(bt_Click);
    
                    panel1.Controls.Add(bt);
    
                }
            }
            private string folder;
            public string Folder
            {
                get { return folder; }
                set { folder = value; }
            }
            void bt_Click(object sender, EventArgs e)
            {
                folder = ((Button)sender).Text;
            }
        }
    }
    

    如你所见,我动态创建了一批按钮,并且他们的背景色是随机产生的,这就增加了一些趣味性,不是吗

    到这里为止,我们针对数据源组件的开发全部介绍完了。下一篇开始将介绍到转换组件和目标组件。但是对于它们与数据源组件相似的地方,例如自定义属性和自定义编辑器,我们都不会重复介绍了。

    本文由作者:陈希章 于 2009/6/21 16:31:09 发布在:http://www.cnblogs.com/chenxizhang/
    本文版权归作者所有,可以转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    更多博客文章,以及作者对于博客引用方面的完整声明以及合作方面的政策,请参考以下站点:陈希章的博客中心
  • 相关阅读:
    1337:【例3-2】单词查找树
    1336:【例3-1】找树根和孩子
    1301:大盗阿福
    CSP-J/S 第一轮知识点选讲
    【转】C++STL各容器的操作及复杂度
    如何查看SUSE的版本信息
    野人和传教士过河问题的C语言源代码
    ubuntu如何安装软件
    Heavy Transportation POJ
    Heavy Transportation POJ
  • 原文地址:https://www.cnblogs.com/chenxizhang/p/1507812.html
Copyright © 2011-2022 走看看