一. 用户能够透过主窗体中的菜单打开数据检索对话框,思量父窗体修改子窗体怎么着完成

  在支付WinForm窗体程序时,大家盼望大增一个对DataGridView数据实行查找的对话框,类似于Visual
Studio中的“查找和替换”对话框,不过效果未有这么复杂,供给如下:

  一. 用户能够通过主窗体中的菜单打开数据检索对话框。

 

  二. DataGridView数据未加载前不突显查找对话框。

建议Windows窗体间音讯传递的标题:怎么样依据子窗体的情形更改父窗体的境况?如双击DataGridView的行记录后弹出修改该行记录的子窗体,在改动完数据后愿意DataGridView数据刷新,那就需求子窗体文告父窗体刷新数据!
设想在子窗体上移动鼠标,将子窗体鼠标的坐标传递给父窗体的标题栏,如何兑现?反过来在父窗体上活动鼠标,如何传递给子窗体?
经典的做法为格局回调,在父窗体类中注册子窗体的MouseMove事件调用父窗体的Method直接改动标题栏;当然大家也足以将父窗体的对象指针船体给子窗体对象的tag,然后在子窗体的MouseMove事件准将tag转换为父窗体对象,然后修改其标题栏文本。回调方案不会损坏程序的逻辑,也不会损坏程序的包装;而tag对象的传递格局要求求public公开tag对象实例的艺术和属性才足以!
上面分别示例三种方法完结,思量父窗体修改子窗体怎么样促成?!

  叁. 找寻对话框中可以进行高低写相配和全字十一分。

 

  四. 追寻对话框以非格局对话框的方式呈以往主窗体的方面。

//target: implement mouse move on child window, call father Window’s Method
//implement: before Show the ChildWindow, give EventHandler to the childWindow 
//and pick up a local method to the EvenHandler        The Callback Method!!!!
using System;
using System.Windows.Forms;

  5. DataGridView中高亮突显被查找到的根本字所在的行。

namespace infoFromWindows
{
//    TypDefName: infoFromWindows.frmFather  (02000003)
//    Flags     : [NotPublic] [AutoLayout] [Class] [AnsiClass] [BeforeFieldInit]  (00100000)
//    Extends   : 01000001 [TypeRef] System.Windows.Forms.Form
    class frmFather : System.Windows.Forms.Form
    {
        private Button btnAbout;
        
        private  frmFather()
        {
            btnAbout = new Button();
            btnAbout.ForeColor = System.Drawing.Color.Green;
            btnAbout.Text=”&About Me”;
            btnAbout.Click += new System.EventHandler(this.btnAboutClick);
            this.Width=400;
            this.Controls.Add(btnAbout);
        }
        
        //this method will be called from child window WHEN mouse move on Child Window
        //notice here, private void …        question: who is the “sender”?
        private void SetChildPosToFather(object sender, MouseEventArgs e)
        {
            string strPos = string.Format( “Child Mouse POS:({0},{1})”,e.X,e.Y);
            this.Text = strPos;
            
            Form about = (Form) sender;
            about.Width=400;
            about.Text=string.Format( “Current Mouse POS:({0},{1})”,e.X,e.Y);
        }
        
        private void btnAboutClick(object sender,System.EventArgs e)
        {
            Form about = new Form();
            //here, we give the child window a EventHandler to call local Method!!!
            about.MouseMove += new MouseEventHandler(SetChildPosToFather);
            about.Show();
        }
                
        private static void Main()
        {
            frmFather father = new frmFather();
            Application.Run(father);
        }
    }
}

  陆.
用户能够在物色对话框中DataGridView中的数据实行巡回查找,即用户每进行三次搜索,DataGridView都将从上3遍查找到的岗位上马向下开始展览检索直到最后一行,然后再从第三行早先继续寻找。

 

  柒. 可对DataGridView实行逐行逐列查找。

tag传递

  对DataGridView进行逐行逐列的遍历并同盟关键字然后高亮显示当前行,这几个作用达成起来应当未有怎么难度,关键在于怎样完结循环查找,并且可以很好地与子窗体(查找对话框)实行互动。其余正是亟需贯彻大小写相配和天地相称,那里供给接纳到正则表明式。大家先看一下先后的主界面。

using System;
using System.Windows.Forms;
using System.Collections.Generic;

澳门永利娱乐总站 1   主窗体的落成自身在那边不具体介绍了,那不是本文的严重性,况且上边这几个程序截图中还落实了无数任何的机能。笔者在那里首要介绍一下窗体的成效以及哪些兑现DataGridView数据的轮回查找。

namespace infoFromWindows
{
    public class frmAbout : Form
    {
        public frmAbout()
        {
            this.Text=”I’m Child Window”;
            this.MouseMove += new MouseEventHandler(changeFatherText);
        }
        
        private void changeFatherText(object sender, MouseEventArgs e)
        {
            frmFather father = (frmFather) this.Tag;
            father.Text = string.Format( “Child Mouse POS:({0},{1})”,e.X,e.Y);
        }
    }
    
//    TypDefName: infoFromWindows.frmFather  (02000003)
//    Flags     : [NotPublic] [AutoLayout] [Class] [AnsiClass] [BeforeFieldInit]  (00100000)
//    Extends   : 01000001 [TypeRef] System.Windows.Forms.Form
    class frmFather : System.Windows.Forms.Form
    {
        private Button btnAbout;
        
        private void btnAboutClick(object sender,System.EventArgs e)
        {
            frmAbout about = new frmAbout();
            about.Tag = this;    
            //here,we transfer current Form POINT to “about” window, 
            //then from “about” window 
            //we can access current Form any PUBLIC method and properties.
            about.Show();
        }
        
        public frmFather()
        {
            btnAbout = new Button();
            btnAbout.ForeColor = System.Drawing.Color.Green;
            btnAbout.Text=”&About Me”;
            btnAbout.Click += new System.EventHandler(this.btnAboutClick);
            this.Width=400;
            this.Controls.Add(btnAbout);
        }
        
        
        public static void Main()
        {
            frmFather father = new frmFather();
            Application.Run(father);
        }
    }
}

 

 

先来看一下什么制作三个相持美观的检索对话框

利用回调实现双窗口通信,尝试开启八个窗口1起测试

  如上图,你能够将用以安装查询参数部分的控件(Match case,Match whole
word)放到二个搭架子控件中,如Group博克斯。那样界面看起来会比较专业一些。然后你还要求对子窗体进行局地参数设置,使其看起来更像贰个对话框。

using System;
using System.Windows.Forms;
using System.Collections.Generic;

  FormBorderStyle: FixedDialog

namespace infoFromWindows
{
    public class frmAbout : Form
    {
        public frmAbout()
        {
            this.Text=”I’m Child Window”;
        }
        
        
        //public, called by father window through MouseMove Event
        public void ChangeColor(object sender, MouseEventArgs e)
        {
            this.BackColor = System.Drawing.Color.FromArgb(e.X,e.Y,0);
        }
    }
    
//    TypDefName: infoFromWindows.frmFather  (02000003)
//    Flags     : [NotPublic] [AutoLayout] [Class] [AnsiClass] [BeforeFieldInit]  (00100000)
//    Extends   : 01000001 [TypeRef] System.Windows.Forms.Form
    class frmFather : System.Windows.Forms.Form
    {
        private Button btnAbout;
        
        
        public frmFather()
        {
            btnAbout = new Button();
            btnAbout.ForeColor = System.Drawing.Color.Green;
            btnAbout.Text=”&About Me”;
            btnAbout.Click += new System.EventHandler(this.btnAboutClick);
            this.Height=255;
            this.Width=255;
            this.MaximizeBox = false;
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
            this.Controls.Add(btnAbout);
        }
        
        private void GetChildPosCallFromFather(object sender,MouseEventArgs e)
        {
            this.Text=string.Format(“({0},{1})”,e.X,e.Y);
        }
        
        private void btnAboutClick(object sender,System.EventArgs e)
        {
            frmAbout about = new frmAbout();
            //here,we transfer current Form POINT to “about” window, 
            //then from “about” window 
            //we can access current Form any PUBLIC method and properties.
            about.Show();
            about.MouseMove += new MouseEventHandler(GetChildPosCallFromFather);
            this.MouseMove += new MouseEventHandler(about.ChangeColor);
        }
        
        public static void Main()
        {
            frmFather father = new frmFather();
            Application.Run(father);
        }
    }
}

  Text: Find Record

 

  Name: FindRecord

  StartPosition: CenterScreen

  AcceptButton: btFindNext (Find Next按钮)

  CancelButton: btCancel (Cancel按钮)

  MaximizeBox: False

  MinimizeBox: False

  ShowIcon: False

  ShowInTaskbar: False

  TopMost: True

 

给对话框扩大部分效用

  首先对话框应该是在大局有效的,不然大家就不能够记录每三遍搜索后DataGridView中被打中的笔录的Index。所以对话框窗体的实例应该是在主窗体中被开首化,并且只被实例化一回。每一次打开对话框时只是调用实例的Show()方法,关闭对话框时只调用窗体的Hide()方法而不是Close()方法,因为Close()方法会将窗体的实例在内存中收回掉。那么大家需求定义btCancel按钮的事件和重写窗体的FormClosing事件并在中间调用窗体的Hide()方法。

  查询参数中的大小写相配和全字至极都是复选框控件,那意味参数会有多样结缘措施,无妨将这一个整合定义成3个枚举,一共是种种情形:任意相配(None),大小写相配(MatchCase),全字相称(MatchWholeCase),大小写和全字非常(MatchCaseAndWholeWord)。

  以事件模型来落到实处数据检索作用在此处再好然则了。首先需求在询问对话框中定义八个伊芙ntHandler,然后在主窗体中订阅这么些事件,事件的实施代码写到子窗体的btFindNext按钮的事件中,一共传递几个参数:查询内容,DataGridView的日前行号(用于固定下三次搜索),以及询问参数枚举变量。上边是子窗体的实际贯彻代码:

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 }

 

主窗体做了怎样

  首先大家须求在主窗体中实例化子窗体并定义查询事件,因而下边这几行代码是必须的:

 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 }

  FindRecord即子窗体所在的类。下边是现实的数码查询达成及菜单响应代码:

 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 }

  tlbFind_Click是菜单点击事件,在突显子窗体前大家须求经过DataLoaded变量来判断DataGridView是还是不是业已完毕多少加载了,那是三个布尔变量,在主窗体中定义的个体变量。Form一_KeyDown事件用来响应Ctrl

  • F快速键,假若DataGridView已经实现多少加载并且用户选取了键盘上的Ctrl +
    F组合键,则实行与tblFind_Click事件相同的操作,那是通过tlbFind.PerformClick()那条语句来形成的。

  winFind_OnFindClick事件达成了切实的数码查询操作,那个事件是子窗体数据查询伊夫ntHandler的切实可行落实。还记得前边提到过的这几个呢?大家在子窗体的那一个伊夫ntHandler中定义了多个参数,用来传递要查询的始末,以及DataGridView的行号和查询参数枚举值。今后在主窗体的这么些事件函数中能够透过对象e来获得到那么些值。代码中经过多少个foreach语句来逐行逐列遍历DataGridView,字符串相称操作使用了正则表明式,依照查询参数中的枚举值来利用区别的正则表明式相称项:

  一.
私下认可意况下正则表明式相配项被设置成了大大小小写敏感(RegexOptions.IgnoreCase)

  二.
假诺用户在子窗体中选拔了尺寸写相称,则将正则表明式相称项修改成None(RegexOptions.None)

  三.
假设用户在子窗体中甄选了全字相当,则使用自定义的正则表达式进行相配。在正则表明式中,’\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值,则持续向下搜寻,直到找到下3个相配的行,且那些行号要超越CurrentIndex值。借使已经找到DataGridView的结尾1行则弹出2个提醒音讯。bFind布尔变量用于提示是或不是已经找到相配的值,要是未有找到,则在先后的终极会弹出3个提示新闻。

 

  好了,程序的具有中央完成都在那里了。其实正是接纳了几许小技巧,再正是子窗体通过事件模型去驱动主窗体的数量查询作用,那比平素在子窗体中定义二个public类型的措施要优雅得多,因为那样做幸免了在差别的窗体间传递参数的麻烦,代码特别简明!

相关文章