以WinForm中增查询对话框对DataGridView数据进行巡回查找。WinForm 窗体间传递数据的片办法[转]

  于开WinForm窗体程序时,我们盼望增加一个对DataGridView数据开展搜的对话框,类似于Visual
Studio中之“查找和替换”对话框,但是效果尚未如此复杂,需求如下:

 

  1. 用户可透过主窗体中的菜单打开数据检索对话框。

方法一

  2. DataGridView数据不加载前未出示搜对话框。

每当子窗体中由定义一个构造函数,参数类型是主窗体,当要显示子窗体的时刻,就因故者构造函数来实例化子窗体,然后把this指针传上。代码如下:

  3. 找对话框中好进行高低写匹配与咸字相当。

主窗体.cs

  4. 招来对话框以非模式对话框的花样显得在主窗体的地方。

   public class frmMain:Form
   {
        …
        frmControl controlForm=new frmControl(this);
        controlForm.Show();
    }

  5. DataGridView中高亮显示为翻找到的重要字所当的行。

子窗体.cs

  6.
用户可于追寻对话框中DataGridView中之数额进行巡回查找,即用户每进行相同糟糕搜索,DataGridView都将于达同蹩脚查找到的岗位上马通往下开展检索直到最终一实践,然后还由第一履开始继续搜寻。

图片 1图片 2子窗体.cs

  7. 可针对DataGridView进行逐行逐列查找。

    public class frmControl:Form  //子窗体,用来决定主窗体的一些显示!
    {
         private frmMain mainForm;
         public frmControl(frmMain mainForm)
         {
              this.mainForm=mainForm;
         }
         private void button1_Click(object sender,EventArgs e)
         {
               frmMain.textBox1.Text=this.textBox1.Text;  
               //把子窗体的文件框值传递让主窗体的文本框!
         }
     }

  对DataGridView进行逐行逐列的遍历并配合关键字然后高亮显示当前执行,这个功效实现起来应当没啊难度,关键在于如何落实循环查找,并且会挺好地跟子窗体(查找对话框)进行相互。另外就是内需贯彻大小写匹配和领域匹配,这里要运用到正则表达式。我们事先押一下序的主界面。

方法二

图片 3   主窗体的兑现自己于这边不现实介绍了,这不是本文的根本,况且上面是顺序截图中还实现了众任何的功力。我在此地要介绍一下窗体的力量及哪促成DataGridView数据的巡回查找。

骨子里方法一致请勿是那个好,虽然实现起来非常粗略,只是想转窗体的标题文本,就拿任何主窗体的援都传送给子窗体,这样的方法不是好优雅,我们之所以接口来改善地方的点子,这样可以界定暴露给子窗体的效力,降低窗体之间的耦合度。代码如下:

 

概念接口.cs

优先来拘禁一下如何打造一个相对美观的搜对话框

    public interface IChangeTitle:
    {
        void ChangeTitle(string title);
    }

  如齐图,你可以用于安装查询参数有的控件(Match case,Match whole
word)放到一个布局控件被,如GroupBox。这样界面看起会比较正规有。然后你还欲对窗体进行一些参数设置,使该扣留起还如一个对话框。

主窗体.cs

  FormBorderStyle: FixedDialog

图片 4图片 5主窗体.cs

  Text: Find Record

   public class frmMain:Form,IChangeTitle
   {
        …
        frmControl controlForm=new frmControl(this);
        controlForm.Show();
        public void ChangeTitle(string title)
        {
             this.Text=title;
        }        
    }

  Name: FindRecord

子窗体.cs

  StartPosition: CenterScreen

图片 6图片 7子窗体.cs

  AcceptButton: btFindNext (Find Next按钮)

    public class frmControl:Form  //子窗体,用来控制主窗体的某些显示!
    {
         private IChangeTitle ichangeTitle;
         public frmControl(IChangeTitle ichangeTitle)
         {
              this.ichangeTitle=ichangeTitle;
         }
         private void button1_Click(object sender,EventArgs e)
         {
              // 通过接口来调用方法
              ichangeTitle.ChangeTitle(this.textBox1.Text);
         }
     }

  CancelButton: btCancel (Cancel按钮)

方法三

  MaximizeBox: False

为了更加降低窗体之间的耦合度,我们得据此托来落实之需要。代码如下:

  MinimizeBox: False

主窗体.cs

  ShowIcon: False

图片 8图片 9主窗体.cs

  ShowInTaskbar: False

    // 主窗体给寄变量赋值就足以了:
    public partial class MainForm : Form
    {
        private ChildForm loginForm = new ChildForm(); 
        public MainForm()
        {
            InitializeComponent();
            loginForm.TitleChanged = new  
                ChildForm.TitleChangedEventHandler(FormTitleChanged);
        }

  TopMost: True

        protected void FormTitleChanged(string title)
        {
            this.Text = title;
        }

 

        private void button1_Click(object sender, EventArgs e)
        {
            loginForm.Show();
        }
    }

叫对话框增加一些意义

子窗体.cs

  首先对话框应该是当全局中的,否则我们尽管未可知记录每一样差搜索后DataGridView中给击中的记录之Index。所以对话框窗体的实例应该是于主窗体中叫初始化,并且独自让实例化一赖。每次打开对话框时只是调用实例的Show()方法,关闭对话框时只调用窗体的Hide()方法而未是Close()方法,因为Close()方法会将窗体的实例在内存中取消掉。那么我们得定义btCancel按钮的事件和重写窗体的FormClosing事件并于其间调用窗体的Hide()方法。

图片 10图片 11子窗体.cs

  查询参数中之轻重写匹配与咸配相当都是复选框控件,这代表参数会有多种重组方式,不妨以这些组合定义成一个枚举,一共是四栽状况:任意匹配(None),大小写匹配(MatchCase),全字匹配(MatchWholeCase),大小写及全配相当(MatchCaseAndWholeWord)。

    public partial class ChildForm : Form
    {
        // 声明和定义委托
        public delegate void TitleChangedHandler(string title);
        public TitleChangedEventHandler TitleChanged;

  为事件模型来落实数据检索功能以此间再好不过了。首先需要在查询对话框中定义一个EventHandler,然后在主窗体中订阅者波,事件之实行代码写到分窗体的btFindNext按钮的波中,一共传递三个参数:查询内容,DataGridView的目前行号(用于固定下一样涂鸦找),以及查询参数枚举变量。下面是分窗体的具体贯彻代码:

        public ChildForm()
        {
            InitializeComponent();
        }   
        private void btn_Ok_Click(object sender, EventArgs e)
        {            
            if (TitleChanged != null)
                TitleChanged(“Test Title”); //委托调用
            
        }
    }

1 using
System;
2 using
System.Collections.Generic;
3 using
System.ComponentModel;
4 using
System.Data;
5 using
System.Drawing;
6 using
System.Linq;
7 using
System.Text;
8 using
System.Windows.Forms;

10 namespace
ListItemEditor.UI
11 {
12     public partial class
FindRecord : Form
13     {
14         public
EventHandler<FindRecordWindowEventArgs>
OnFindClick = null;
15         public enum
FindOptions { None, MatchCase, MatchWholeWord, MatchCaseAndWholeWord }
16         public int
CurrentIndex = -1;
17 
18         public
FindRecord()
19         {
20             InitializeComponent();
21         }
22 
23         private void
btCancel_Click(object sender, EventArgs e)
24         {
25             this.Hide();
26         }
27 
28         private void
FindRecord_FormClosing(object
sender, FormClosingEventArgs e)
29         {
30             this.Hide();
31             e.Cancel = true;
32         }
33 
34         private void
btFindNext_Click(object sender, EventArgs e)
35         {
36             if
(this.tbFindTxt.Text.Trim().Length > 0)
37             {
38                 FindOptions options =
FindOptions.None;
39                 if
(this.chbMatchCase.Checked && this.chbMatchWholeWord.Checked)
40                 {
41                     options =
FindOptions.MatchCaseAndWholeWord;
42                 }
43                 else if
(this.chbMatchCase.Checked && !this.chbMatchWholeWord.Checked)
44                 {
45                     options =
FindOptions.MatchCase;
46                 }
47                 else if
(!this.chbMatchCase.Checked && this.chbMatchWholeWord.Checked)
48                 {
49                     options =
FindOptions.MatchWholeWord;
50                 }
51                 else
52                 {
53                     options =
FindOptions.None;
54                 }
55                 OnFindClick(this,
new FindRecordWindowEventArgs(this.tbFindTxt.Text, CurrentIndex, options));
56             }
57         }
58     }
59 
60     public class
FindRecordWindowEventArgs : EventArgs
61     {
62         private string
sFindTxt;
63         private int iIndex
= 0;
64         private
FindRecord.FindOptions findOptions;
65 
66         public string
FindTxt
67         {
68             get {
return this.sFindTxt; }
69         }
70 
71         public int Index
72         {
73             get {
return this.iIndex;
}
74         }
75 
76         public
FindRecord.FindOptions FindOptions
77         {
78             get {
return this.findOptions; }
79         }
80 
81         public
FindRecordWindowEventArgs(string
_findTxt, int _index, FindRecord.FindOptions _options)
82         {
83             this.sFindTxt
= _findTxt;
84             this.iIndex
= _index;
85             this.findOptions =
_options;
86         }
87     }
88 }

方法四

 

为得在子窗体中定义一个自定义的波,然后从定义一个事件参数,用来传递您想传递的有的信。代码如下:
主窗体.cs

主窗体做了什么

图片 12图片 13主窗体.cs

  首先我们用在主窗体中实例化子窗体并定义查询事件,因此下这几实践代码是须的:

    // 主窗体订阅者事件就是好了
    public partial class MainForm : Form
    {
        private ChildForm loginForm = new ChildForm(); 
        public MainForm()
        {
            InitializeComponent();
            loginForm.TitleChanged += 
            new ChildForm.TitleChangedEventHandler(FormTitleChanged);
        }

 1 public partial class Form1 : Form
 2 {
 3     private FindRecord winFind = new FindRecord();
 4 
 5     public Form1()
 6     {
 7         InitializeComponent();
 8 
 9         this.winFind.OnFindClick += new EventHandler<FindRecordWindowEventArgs>(this.winFind_OnFindClick);
10     }
11 }

        protected void FormTitleChanged(object sender, ChildForm.TitleChangedEventArgs e)
        {
            this.Text = e.Title;
        }

  FindRecord即子窗体所于的类似。下面是具体的数额查询实现与菜单响应代码:

        private void button1_Click(object sender, EventArgs e)
        {
            loginForm.Show();
        }
    }

 1 private void tlbFind_Click(object sender, EventArgs e)
 2 {
 3     if (!this.DataLoaded) return;
 4     winFind.Show();
 5 }
 6 
 7 private void Form1_KeyDown(object sender, KeyEventArgs e)
 8 {
 9     if (!this.DataLoaded) return;
10     if (e.Modifiers == Keys.Control && e.KeyCode == Keys.F)
11     {
12         tlbFind.PerformClick();
13     }
14 }
15 
16 private void winFind_OnFindClick(object sender, FindRecordWindowEventArgs e)
17 {
18     string s = e.FindTxt;
19     int index = e.Index;
20     bool bFind = false;
21 
22     RegexOptions regOptions = RegexOptions.IgnoreCase;
23     string pattern = Regex.Escape(s);
24 
25     if (e.FindOptions == FindRecord.FindOptions.MatchCase || e.FindOptions == FindRecord.FindOptions.MatchCaseAndWholeWord)
26     {
27         regOptions = RegexOptions.None;
28     }
29 
30     if (e.FindOptions == FindRecord.FindOptions.MatchWholeWord || e.FindOptions == FindRecord.FindOptions.MatchCaseAndWholeWord)
31     {
32         pattern = “\\b” + pattern + “\\b”;
33     }
34 
35     foreach (DataGridViewRow row in theGrid.Rows)
36     {
37         this.winFind.CurrentIndex = row.Index;
38         foreach (DataGridViewCell cel in row.Cells)
39         {
40             //if (cel.Value.ToString().Contains(s))
41             if (Regex.IsMatch(cel.Value.ToString(), pattern, regOptions))
42             {
43                 bFind = true;
44                 if (cel.RowIndex > index)
45                 {
46                     this.theGrid.ClearSelection();
47                     this.theGrid.Rows[cel.RowIndex].Selected = true;
48                     return;
49                 }
50             }
51         }
52     }
53 
54     if (this.winFind.CurrentIndex == this.theGrid.Rows.Count – 1 && bFind)
55     {
56         this.winFind.CurrentIndex = -1;
57         MessageBox.Show(“Find the last record.”, “List Item Editor”, MessageBoxButtons.OK, MessageBoxIcon.Information);
58         return;
59     }
60 
61     if (!bFind)
62     {
63         this.winFind.CurrentIndex = -1;
64         MessageBox.Show(string.Format(“The following specified text was not found:\r\n{0}”, s), “List Item Editor”, MessageBoxButtons.OK, MessageBoxIcon.Information);
65     }
66 }

子窗体.cs

  tlbFind_Click是菜单点击事件,在显示子窗体前我们要经过DataLoaded变量来判断DataGridView是否早已就数据加载了,这是一个布尔变量,在主窗体中定义的民用变量。Form1_KeyDown事件就此来响应Ctrl

图片 14图片 15子窗体.cs

  • F快捷键,如果DataGridView已经完成多少加载并且用户采取了键盘上的Ctrl +
    F组合键,则行和tblFind_Click事件相同之操作,这是经tlbFind.PerformClick()这条告句子来好的。

    public partial class ChildForm : Form
    {
        public class TitleChangedEventArgs : EventArgs // 事件参数近似
        {
            private string title = “”;
            public string Title
            {
                get{ return title; }
                set{ title = value; }
            }
        }
        // 声明委托
        public delegate void TitleChangedEventHandler(object sender, TitleChangedEventArgs e);
        // 定义事件
        public event TitleChangedEventHandler TitleChanged;

  winFind_OnFindClick事件实现了切实可行的数额查询操作,这个波是分支窗体数据查询EventHandler的切实可行实现。还记前面提到过的之也?我们于子窗体的这个EventHandler中定义了三个参数,用来传递要查询的情节,以及DataGridView的行号和查询参数朵举值。现在以主窗体的这个事件函数中得经对象e来抱到这些价值。代码中通过简单单foreach语句来逐行逐列遍历DataGridView,字符串匹配操作使用了正则表达式,根据查询参数中之枚举值来使用不同之正则表达式匹配项:

        public ChildForm()
        {
            InitializeComponent();
        }
     
        private void btn_Ok_Click(object sender, EventArgs e)
        {
            TitleChangedEventArgs e1=new TitleChangedEventArgs();
            e1.Title=”Login sucessed”;
            OnTitleChanged(e1);// 触发事件
            
        }
        // 触发事件之主意
        protected virtual void OnTitleChanged(TitleChangedEventArgs e)
        {
            if (TitleChanged != null)
                TitleChanged(this, e);
        }
    }

  1.
默认情况下正则表达式匹配项于装成了大小写敏感(RegexOptions.IgnoreCase)

来源:http://www.cnblogs.com/xuefeng1982/archive/2010/06/11/1756620.html

  2.
而用户在子窗体中精选了大大小小写匹配,则用正则表达式匹配项修改成None(RegexOptions.None)

  3.
假如用户在子窗体中挑选了净字相当,则利用由定义的正则表达式进行匹配。在正则表达式中,’\b’用来判定单词边界,而’\B’用来判断非单词边界。有关如何使正则表达式进行全字匹配可以参照下此的均等篇稿子。

http://answers.oreilly.com/topic/217-how-to-match-whole-words-with-a-regular-expression/

  正则表达式30分钟入门教程为有关于如何利用\b和\B的介绍,并且描述简单明了。

  子窗体中还有一个集体整型变量CurrentIndex,主窗体在遍历DataGridView的以会修改是价值,将DataGridView的脚下行号传递回子窗体,当用户下一致浅开展询问时,子窗体又见面以以此行号传回到主窗体中。你应该已经注意到了以内层的foreach循环语句被发出一个断定,如果命中之DataGridView行的行号小于CurrentIndex值,则连续朝着下搜寻,直到找到下一个配合的履,且这行号要大于CurrentIndex值。如果既找到DataGridView的末段一实行虽然弹有一个提示信息。bFind布尔变量用于指示是否业已找到匹配的价,如果没有找到,则在先后的最终会弹有一个提示信息。

 

  好了,程序的有着骨干实现都以此处了。其实就是是应用了几许有点技巧,再就是子窗体通过波模型去让主窗体的数量查询功能,这比较直接在子窗体中定义一个public类型的方式而优雅得几近,因为这样做避免了于不同之窗体间传递参数的辛苦,代码更加简明!

相关文章

发表评论

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