孙鑫第8课--对话框的编程(属性页,属性表单)
- 格式:doc
- 大小:71.50 KB
- 文档页数:6
第8章窗体的编辑与设计窗体界面不但要功能全面,而且还要美观大方,并且要按照用户的需求设计出特殊的效果,这时就需要对窗体进行设计。
窗体的各个视图中包含了多种不同的窗体设计工具,通过这些工具可以设计出多种不同的窗体界面。
本章重点:窗体设计工具窗体的基本操作窗体界面设计8.1窗体设计工具在窗体的设计过程中往往想为窗体设置一些特殊的效果,例如将某个字段按照降序排列或者将某个控件设置为固定大小等,这些就需要用到窗体的设计工具。
8.1.1窗体视图工具窗体视图工具主要用于数据的查询和预览等,通常不会在该视图中进行窗体界面和属性的设置。
打开一个窗体视图,切换至【开始】选项卡,可以看到窗体视图中可用的工具,如图8-1所示。
图8-1窗体工具下面我们将简单地介绍这几个工具的功能及用法,如下所示。
·【视图】按钮:单击该按钮,可以将当前视图模式切换至不同的视图模式,如图8-2所示,列出了【窗体视图】、【布局视图】、【设计视图】三种。
图8-2 视图列表·【升序】按钮和【降序】按钮:如果窗体中的字段比较多,那么想要对其重新排序的时候,我们可以单击【排序和筛选】选项组中的【升序】按钮或者【降序】按钮,即可对窗体中的数据进行重新排序。
·【选择】按钮 :该按钮的使用比较简单,在窗体中选择某个字段后单击该按钮,就可以对窗体视图中的数据进行筛选,筛选的结果是与事先选中的数据同样的数据。
单击该按钮,可弹出一个下拉列表,如图8-3所示。
·【清除所有排序】按钮 :单击该按钮,可以清除所有的窗体排序痕迹。
图8-3下拉列表·【高级筛选选项】按钮:单击该按钮,在弹出的下拉列表中可以选择【按窗体筛选】、【应用筛选/排序】和【高级筛选/排序】等选项,如图8-4所示。
图8-4【高级筛选选项】列表·【应用/取消筛选】按钮:当窗体视图中存在某种筛选时,包括筛选被应用和筛选被取消两种情况,该按钮都将变为可用状态,否则为不可用状态。
WinForm控件开发基础教程八弹出式编辑对话框前几篇文章我们一直在讨论如何更方便的编辑复杂类型的属性,在这个过程中我介绍了类型转换器以及如何制作自己的类型转换器来实现属性值的串行化和实现子属性的编辑。
对于Scope这种级别的复杂属性,一个类型转换器就已经足够了,但是对于更为复杂的属性,单单使用类型转换器已经不足以应付了,比如我们常用的Font属性。
在这种情况下,我们就需要提供更为复杂的编辑方式,比如属性编辑对话框,你还记得Font 对话框吗?现在我们就来看看如何实现更复杂的属性编辑。
复杂的属性编辑器分为两种类型,一种是弹出式模态对话框属性编辑器,一种式下拉式属性编辑器。
如果你还没有感性的认识的话,可以观察一下TextBox控件的属性,Font属性的编辑器是模态对话框属性编辑器,Dock属性的编辑器是下拉式属性编辑器。
接下来我们来制作一个模态对话框编辑器,虽然Scope属性并不复杂,但是为了演示的方便,我们还是用它来做例子。
首先我们要做一个用来编辑属性的对话框,在对话框的构造函数里传入要编辑的属性的值。
在对话框类里,声明一个Scope类型的私有变量_scope用以保存传入和编辑后的值。
还要增加一个Scope属性,以便外部环境能够获取编辑后的结果。
对话框的外观如下:在这个对话框里,我们要把OK按钮的DialogResult属性设为OK(当点击OK按钮时,模态对话框关闭,并返回DialogResult.OK),将Cancel按钮的DialogResult属性设为Cancel(当点击OK按钮时,模态对话框关闭,并返回DialogResult.OK)。
另外我们要对用户输入的值做验证,以保证Scope的min和max值都是Int32类型。
下边是对话框的代码:using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;namespace CustomControlSample{public partial class ScopeEditorDialog : Form{private Scope _scope = null;public ScopeEditorDialog(Scope scope){InitializeComponent();_scope = scope;textBox1.Text = _scope.Min.ToString();textBox2.Text = _scope.Max.ToString();}private void button1_Click(object sender, EventArgs e){_scope.Min = Convert.ToInt32(textBox1.Text);_scope.Max = Convert.ToInt32(textBox2.Text);}private void textBox1_V alidating(object sender, CancelEventArgs e){try{Int32.Parse(textBox1.Text);}catch (FormatException){e.Cancel = true;MessageBox.Show("无效的值", "验证错误", MessageBoxButtons.OK, MessageBoxIcon.Error);}}private void textBox2_V alidating(object sender, CancelEventArgs e){try{Int32.Parse(textBox2.Text);}catch (FormatException){e.Cancel = true;MessageBox.Show("无效的值", "验证错误", MessageBoxButtons.OK, MessageBoxIcon.Error);}}public Scope Scope{get { return _scope; }set { _scope = value; }}}}每一个属性的编辑器都是直接或者间接的派生于UITypeEditor。
第8章表单中控件的设计及应用控件是用于显示数据、执行操作或装饰表单的一种图形对象,如文本框、命令按钮、标签、线条和页框等,通常也将控件称为对象。
在应用程序中,几乎每个功能窗口(表单)中都包含控件,控件是完成各类任务的主要操作对象。
按对象的行为特征可将对象分为以下7类:(1)显示信息类:标签、线条、形状和图像。
(2)控制类:命令按钮和命令按钮组。
(3)编辑类:文本框和编辑框。
(4)列表类:列表框和组合框。
(5)选择类;复选框和选项按钮组。
(6)容器类:表格、页框和Container容器。
(7)其他类:超级链接、计时器和微调控件。
8.1 显示信息类控件显示信息类控件用于在表单上显示文本或图形,这类控件有标签、线条、形状和图像,它们起到显示信息或修饰表单的作用。
8.1.1 标签(Label)标签控件可以在表单中显示文本信息,在表单运行时,无法用鼠标直接对标签中的文本信息进行选取或修改操作,因此,标签控件常用于表单上的提示信息或说明性文字。
标签的常用属性如下:(1)Caption :为标签控件指定标题文本,即在表单上显示的文本信息。
很多控件都有Caption属性,如表单、命令按钮、复选按钮等,其作用是相同的,都是显示文本信息,且属性值的数据类型均为字符型。
(2)AutoSize :设置Autosize属性可以确定标签显示区域的大小是否随标题文本的大小及多少进行变化。
该属性值的数据类型为逻辑型。
当AutoSize属性取值为.T.时,标签显示区域的大小将随标题文本的大小及多少变化;当AutoSize属性取值为.F.时,标签显示区域的大小不随标题文本大小及多少而变。
8.1.2 线条、形状与图像1.线条(Line)线条(Line)用于在表单上画线,如斜线、垂直线和水平线等。
线的走向可以由LineSlant属性来设置,其值为“\”表示从左上角向右下角画线;“/”表示从右上角向左下角画线。
若将线的Width属性值设为0,则得到一条垂直线;若将线的Height属性值设为0,则得到一条水平线。
第8章菜单和通用对话框设计8.1 Visual Basic的菜单两种:下拉式菜单、弹出式菜单每个菜单项看成是一个控件8.1.1 菜单编辑器菜单编辑器:设计菜单的工具进入菜单编辑器的4种方式:(1)“工具”菜单的“菜单编辑器”命令(2)快捷键Ctrl+E(3)工具栏的“菜单编辑器”按钮(4)窗体上快捷菜单“菜单编辑器”菜单编辑器的各项内容和作用:(1)“标题”:相当于菜单控件的Caption属性。
“&+字符”热键。
“-”分隔线(减号、二级菜单)。
(2)“名称”:用来设置菜单项的Name 属性,一般以mnu为前缀。
(3)“索引”:用来建立控件数组的下标。
(4)“快捷键”:可供用户选择的快捷键。
(5)“帮助上下文ID”:帮助文本的标识符,用于确定帮助主题。
(6)“协调位置”:确定菜单是否出现或怎样出现。
(7)“复选”框:确定“√”标记是否放在菜单项前面,表示某种状态。
(8)“有效”框:该菜单项是否可执行。
(9)“可见”框:该菜单项是否可见。
(10)“显示窗口列表”框:在多文档应用时,是否菜单中包含当前打开的文档列表。
(11)菜单显示区:显示菜单项。
(12)编辑按钮:用来对菜单项进行编辑。
8.1.2建立菜单【例8.1】设计一个程序,进行两个运算数的算术运算练习。
功能要求:用户从“位数”菜单中选择操作数的位数(一位数、两位数或三位数),从“运算”菜单中选择一种运算(加法、减法和乘法),单击“命题”按钮后,程序将产生指定位数的两个运算数,并按指定运算组成一个算式,显示在文本框Text1中,供用户练习。
用户在文本框Text2中输入答案,当单击“答题”按钮时,程序将判断答案是否正确,然后通过消息对话框显示出“回答正确”或“回答错误”。
步骤:(1)创建应用程序的用户界面和设置对象属性。
两个标签:“运算题”、“填写答案”两个文本框:显示运算式(右对齐)、输入答案两个按钮:命题、答题窗体Caption属性:“简单算术运算练习”菜单项:位数(mnu10)、一位数(mnu11)、两位数(mnu12)、三位数(mnu13);运算(mnu20)、加法(mnu21)、减法(mnu22)、乘法(mnu23);退出(mnu30)。
选择一个基于对话框的MFC工程。
下面做一个逃跑按钮。
在对话框上添加两个按钮。
新建一个CBtn,基类是CButton.为这个类添加:CBtn *pbtn;为这两个按钮关联新建立的这个按钮类。
在BOOL CTestDlg::OnInitDialog()中添加:m_btn1.pbtn=&m_btn2;m_btn2.pbtn=&m_btn1;void CBtn::OnMouseMove(UINT nFlags, CPoint point){// TODO: Add your message handler code here and/or call defaultShowWindow(SW_HIDE);pbtn->ShowWindow(SW_SHOW);CButton::OnMouseMove(nFlags, point);}运行,达到效果,但是初始化运行的时候能看到两个按钮。
为此做如下修改:将其中一个按钮的可见性不选。
下面是属性表单和向导的创建:创建一个MFC的单文档程序。
为菜单增加一个显示属性表单的按钮,并添加VIEW类中响应。
添加三个属性页对话框。
(由于在上面要写中文,将属性改为中文),并为这三个属性页创建一个类,再新建一个对话框,为它创建一个属性表单类。
在属性表单的头文件中添加:(要包含三个属性页的头文件)public:CPage1 m_page1;CPage2 m_page2;CPage3 m_page3;为属性表单的构造函数:CPageSheet::CPageSheet(UINT nIDCaption, CWnd* pParentWnd, UINT iSelectPage) :CPropertySheet(nIDCaption, pParentWnd, iSelectPage){AddPage(&m_page1);AddPage(&m_page2);AddPage(&m_page3);}CPageSheet::CPageSheet(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage) :CPropertySheet(pszCaption, pParentWnd, iSelectPage){AddPage(&m_page1);AddPage(&m_page2);AddPage(&m_page3);}void CTestView::OnPage(){// TODO: Add your command handler code hereCPageSheet ps("属性表单");ps.SetWizardMode();//设置向导,如没这句,不是设置向导。
ps.DoModal();}CPageSheet类不用关联任何的对话框,直接创建这个类。
为单选按钮关联一个成员变量。
BOOL CPage1::OnSetActive(){// TODO: Add your specialized code here and/or call the base classCPageSheet* psheet = (CPageSheet*) GetParent();psheet->SetWizardButtons(PSWIZB_NEXT);return CPropertyPage::OnSetActive();}BOOL CPage2::OnSetActive(){CPropertySheet* psheet = (CPropertySheet*) GetParent();psheet->SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT);return TRUE;}BOOL CPage3::OnSetActive(){// TODO: Add your specialized code here and/or call the base classCPropertySheet* psheet = (CPropertySheet*) GetParent();psheet->SetWizardButtons(PSWIZB_BACK | PSWIZB_FINISH);return CPropertyPage::OnSetActive();}BOOL CPage1::OnInitDialog(){CPropertyPage::OnInitDialog();// TODO: Add extra initialization here((CListBox*)GetDlgItem(IDC_LIST1))->AddString( "北京" );((CListBox*)GetDlgItem(IDC_LIST1))->AddString( "上海" );((CListBox*)GetDlgItem(IDC_LIST1))->AddString( "广州" );return TRUE; // return TRUE unless you set the focus to a control// EXCEPTION: OCX Property Pages should return FALSE}为列表框控件关联一个列表框成员变量(CSTRING类型)。
LRESULT CPage1::OnWizardNext(){// TODO: Add your specialized code here and/or call the base class//GetText( int nIndex, LPTSTR lpszBuffer ) int GetCurSel( )UpdateData();if (-1==m_radio1){MessageBox("请选择你的职业!!");return -1;}if (m_list==""){MessageBox("请选择你的工作地点!!");return -1;}((CListBox*)GetDlgItem(IDC_LIST1))->GetText(((CListBox*)GetDlgItem(IDC_LIST1))-> GetCurSel( ),m_list );UpdateData(FALSE);return CPropertyPage::OnWizardNext();} LRESULT CPage2::OnWizardNext(){// TODO: Add your specialized code here and/or call the base classUpdateData();if(m_check1==FALSE&&m_check2==FALSE&&m_check3==FALSE&&m_check4==FALSE) {MessageBox("请选择你的兴趣爱好");return -1;}UpdateData(FALSE);return CPropertyPage::OnWizardNext();}将COMBO的SORT项取消。
BOOL CPage3::OnInitDialog(){CPropertyPage::OnInitDialog();// TODO: Add extra initialization here IDC_COMBO1((CComboBox*)GetDlgItem(IDC_COMBO1))->AddString("1000元以下");((CComboBox*)GetDlgItem(IDC_COMBO1))->AddString("1000元--2000元");((CComboBox*)GetDlgItem(IDC_COMBO1))->AddString("2000元--3000元");((CComboBox*)GetDlgItem(IDC_COMBO1))->AddString("3000元--4000元");return TRUE; // return TRUE unless you set the focus to a control// EXCEPTION: OCX Property Pages should return FALSE}为Page3增加:private:CString m_strsalary;BOOL CPage3::OnWizardFinish(){// TODO: Add your specialized code here and/or call the base class//GetLBText( int nIndex, CString& rString ) constint nIndex=((CComboBox*)GetDlgItem(IDC_COMBO1))->GetCurSel();((CComboBox*)GetDlgItem(IDC_COMBO1))->GetLBText( nIndex, m_strsalary );return CPropertyPage::OnWizardFinish();}下面是VIEW类中将用户的选择在VIEW中输出。
为VIEW类增加:private:CString m_zhiye;CString m_strworkaddr;CString m_aihao;CString m_xinzhi;并初始化。
void CTestView::OnPage(){// TODO: Add your command handler code here 篮球,足球,游泳,排球CPageSheet ps("属性表单");ps.SetWizardMode();if(ID_WIZFINISH==ps.DoModal()){if(ps.m_page1.m_radio1==0){m_zhiye="程序员";}if(ps.m_page1.m_radio1==1){m_zhiye="系统工程师";}if(ps.m_page1.m_radio1==2){m_zhiye="项目经理";}m_strworkaddr=ps.m_page1.m_list;if (ps.m_page2.m_check1==TRUE){m_aihao+="篮球";}if (ps.m_page2.m_check2==TRUE){m_aihao+="足球";}if (ps.m_page2.m_check3==TRUE){m_aihao+="游泳";}if (ps.m_page2.m_check4==TRUE){m_aihao+="排球";}m_xinzhi=ps.m_page3.m_strsalary;}Invalidate();}void CTestView::OnDraw(CDC* pDC){CTestDoc* pDoc = GetDocument();ASSERT_V ALID(pDoc);CFont font;font.CreatePointFont(300,"华文行楷");CFont *poldfont=pDC->SelectObject(&font);TEXTMETRIC tm;pDC->GetTextMetrics(&tm) ;pDC->TextOut(0,0,m_zhiye);pDC->TextOut(0,tm.tmHeight,m_strworkaddr);pDC->TextOut(0,tm.tmHeight*2,m_aihao);pDC->TextOut(0,tm.tmHeight*3,m_xinzhi);pDC->SelectObject(poldfont);}。