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/
    本文版权归作者所有,可以转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    更多博客文章,以及作者对于博客引用方面的完整声明以及合作方面的政策,请参考以下站点:陈希章的博客中心
  • 相关阅读:
    极客标签编程小挑战#31:生成注册页面的显示效果
    极客Web前端开发资源大荟萃#017
    知道你们不想撸代码写PPT之可视化页面做一款炫酷的WEB PPT
    使用jQuery图表插件Sparklines来开发一个实用的网站PV(page view)实时监控应用
    javascript专业八级测试答案整理
    使用Raphaël类库实现的超酷动画技能图表
    极客编程小挑战#26:实现日期级联下拉选择框
    gulp初印象
    程序语言,编译?解释?
    发了这嘛多技术文章,今天给大家点福利吧!邻家小美女一枚,想在北京找个工作,大家来看看给出点主意。
  • 原文地址:https://www.cnblogs.com/chenxizhang/p/1507812.html
Copyright © 2011-2022 走看看