Tab Control的运行

 
Tab Control的运行效果有点像Property Sheet,但两者还是有一些区别。我的理解就是Property Sheet主要用在 对话框中,对数据进行进行分类管理。而Tab Control使用范围更广一些,既可以用在对话框,也可以用在视图中,除了可以管理配置数据外,还可以对 软件的组织进行规划,比如可以通过它来切换不同的视图等等。
当然这不是没有代价的,Tab Control的编程就比Property Sheet的复杂很多。
我最初有点搞不懂,如何在Tab Control中使用不同的Page,就象Property Page一样,Tab Control并没有提供便利的机制让你轻松做到这一点。还好,VC是最棒的,撒花~通过变通的方法还是可以做到这一点。
不罗嗦了,上代码。
假如我现在有个SDI程序,View是Form View,想在上面放个Tab Control,包含两个Page。现在让我们来看看应该怎样处理。
首先当然要增加一个Tab Control资源,然后利用Class Wizard,在View中增加一个Control变量。
接着建立两个对话框资源,别忘了把Style改为Child,Border改为None。然后就可以在上面加其他控件了。
接着利用Class Wizard,分别为这两个对话框建立两个类,比如CPage1和CPage2。
然后在View类头文件中,加入这两个对话框对象。同时增加一个变量int m_CurSelTab,用了表明是哪个Page即将被切换。
为了避免用户在切换Tab时,程序对Tab Index的枚举,可以利用数组来做这个事情。
在View的初始化函数中需要把CPage1、CPage2和Tab Control关联起来,并保存页面地址,设置初始页面,等等。
void CTab_testView::OnInitialUpdate()
{
    CFormView::OnInitialUpdate();
    GetParentFrame()->RecalcLayout();
    ResizeParentToFit();
     
     //为Tab Control增加两个页面
     m_tab.InsertItem(0, _T("First"));
     m_tab.InsertItem(1, _T("Second"));
    
     //创建两个对话框
     m_page1.Create(IDD_DIALOG1, &m_tab);
     m_page2.Create(IDD_DIALOG2, &m_tab);
     //设定在Tab内显示的范围
     CRect rc;
     m_tab.GetClientRect(rc);
     rc.top += 20;
     rc.bottom -= 8;
     rc.left += 8;
     rc.right -= 8;
     m_page1.MoveWindow(&rc);
     m_page2.MoveWindow(&rc);
     //把对话框对象指针保存起来
     pDialog[0] = &m_page1;
     pDialog[1] = &m_page2;
     //显示初始页面
     pDialog[0]->ShowWindow(SW_SHOW);
     pDialog[1]->ShowWindow(SW_HIDE);
     //保存当前选择
     m_CurSelTab = 0;
}
这里面需要注意的是,我用了一个CDialog指针数组来进行保存,数组的大小是Tab Control页面的个数,数组下标对应着每个页面的索引(这样方便快速存取)。
用户切换时,需要响应相关的消息。
void CTab_testView::OnSelchangeTab1(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
    
     pDialog[m_CurSelTab]->ShowWindow(SW_HIDE);
     m_CurSelTab = m_tab.GetCurSel();
     pDialog[m_CurSelTab]->ShowWindow(SW_SHOW);
*pResult = 0;
}
首先我们先把当前的页面隐藏起来,然后得到新的页面索引,最后就把相关页面显示出来即可。这比一个个去枚举简单多了。
还有一点比较有意思,那就是DDX/DDV机制的运用。要想获得Tab Control各个页面的数据,可以利用DDX/DDV机制,但需要注意,因为这是多个页面,所以需要显式调用多次。
void CTab_testView::OnButton1()
{
// TODO: Add your control notification handler code here
     m_page1.UpdateData();
     m_page2.UpdateData();
     CString str1 = m_page1.m_str1;
     CString str2 = m_page2.m_str2;
     AfxMessageBox(str1);
     AfxMessageBox(str2);
}
经过这几步处理,基本上我们就可以利用Tab Control的强大功能了
 
很好的一篇文章,内容精炼, Author: 永不消逝的蓝
说实话,我刚开始看见 Tab Control 的时候,觉得很简单。哪知道用了一下,才发现自己错了。
要用好它,还是需要一些技巧的。经过网上搜索资料,以及我自己的摸索,把一些要点记录在这里。
Tab Control 的运行效果有点像 Property Sheet ,但两者还是有一些区别。我的理解就是 Property Sheet 主要用在对话框中,对数据进行进行分类管理。而 Tab Control 使用范围更广一些,既可以用在对话框,也可以用在视图中,除了可以管理配置数据外,还可以对软件的组织进行规划,比如可以通过它来切换不同的视图等等。
当然这不是没有代价的, Tab Control 的编程就比 Property Sheet 的复杂很多。
  我最初有点搞不懂,如何在 Tab Control 中使用不同的 Page ,就象 Property Page 一样, Tab Control 并没有提供便利的机制让你轻松做到这一点。还好, VC 是最棒的,撒花~通过变通的方法还是可以做到这一点。
不罗嗦了,上代码。
假如我现在有个 SDI 程序, View Form View ,想在上面放个 Tab Control ,包含两个 Page 。现在让我们来看看应该怎样处理。
首先当然要增加一个 Tab Control 资源,然后利用 Class Wizard ,在 View 中增加一个 Control 变量。
接着建立两个对话框资源,别忘了把 Style 改为 Child Border 改为 None 。然后就可以在上面加其他控件了。
接着利用 Class Wizard ,分别为这两个对话框建立两个类,比如 CPage1 CPage2
然后在 View 类头文件中,加入这两个对话框对象。同时增加一个变量 int m_CurSelTab ,用了表明是哪个 Page 即将被切换。
为了避免用户在切换 Tab 时,程序对 Tab Index 的枚举,可以利用数组来做这个事情。
View 的初始化函数中需要把 CPage1 CPage2 Tab Control 关联起来,并保存页面地址,设置初始页面,等等。
void CTab_testView::OnInitialUpdate()
{
   CFormView::OnInitialUpdate();
   GetParentFrame()->RecalcLayout();
   ResizeParentToFit();
     
    //
Tab Control 增加两个页面
    m_tab.InsertItem(0, _T("First"));
    m_tab.InsertItem(1, _T("Second"));
    
    //
创建两个对话框
    m_page1.Create(IDD_DIALOG1, &m_tab);
    m_page2.Create(IDD_DIALOG2, &m_tab);
    // 设定在 Tab 内显示的范围
    CRect rc;
    m_tab.GetClientRect(rc);
    rc.top += 20;
    rc.bottom -= 8;
    rc.left += 8;
    rc.right -= 8;
    m_page1.MoveWindow(&rc);
    m_page2.MoveWindow(&rc);
    // 把对话框对象指针保存起来
    pDialog[0] = &m_page1;
    pDialog[1] = &m_page2;
    // 显示初始页面
    pDialog[0]->ShowWindow(SW_SHOW);
    pDialog[1]->ShowWindow(SW_HIDE);
    // 保存当前选择
    m_CurSelTab = 0;
}
这里面需要注意的是,我用了一个 CDialog 指针数组来进行保存,数组的大小是 Tab Control 页面的个数,数组下标对应着每个页面的索引(这样方便快速存取)。
用户切换时,需要响应相关的消息。
void CTab_testView::OnSelchangeTab1(NMHDR* pNMHDR, LRESULT* pResult) 
{
 // TODO: Add your control notification handler code here
    
    pDialog[m_CurSelTab]->ShowWindow(SW_HIDE);
    m_CurSelTab = m_tab.GetCurSel();
    pDialog[m_CurSelTab]->ShowWindow(SW_SHOW);
 *pResult = 0;
}
首先我们先把当前的页面隐藏起来,然后得到新的页面索引,最后就把相关页面显示出来即可。这比一个个去枚举简单多了。
还有一点比较有意思,那就是 DDX/DDV 机制的运用。要想获得 Tab Control 各个页面的数据,可以利用 DDX/DDV 机制,但需要注意,因为这是多个页面,所以需要显式调用多次。
void CTab_testView::OnButton1() 
{
 // TODO: Add your control notification handler code here
    m_page1.UpdateData();
    m_page2.UpdateData();
    CString str1 = m_page1.m_str1;
    CString str2 = m_page2.m_str2;
    AfxMessageBox(str1);
    AfxMessageBox(str2);
}
经过这几步处理,基本上我们就可以利用 Tab Control 的强大功能了。
 
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值