MFC CListCtrl::SetItemText() 不工作

Posted

技术标签:

【中文标题】MFC CListCtrl::SetItemText() 不工作【英文标题】:MFC CListCtrl::SetItemText() not working 【发布时间】:2016-02-10 10:56:41 【问题描述】:

我是构建 MFC 应用程序的初学者。我刚刚开始使用列表控件(在报告视图中),并且在更新列表时遇到了一些问题。我有三个按钮用于添加、更新和删除。除更新外,一切正常。这是代码。

void CAddDetailsDlg::DoDataExchange(CDataExchange* pDX)

    CDialogEx::DoDataExchange(pDX); 
    DDX_Control(pDX, IDC_DEPARTMENT, departmentControl);
    DDX_Text(pDX, IDC_NAME, m_name);
    DDX_Text(pDX, IDC_ID, m_id);
    DDX_Text(pDX, IDC_AGE_BUDDY, m_ageVariable);
    DDX_CBString(pDX, IDC_DEPARTMENT, m_department);
    DDX_Control(pDX, IDC_LIST1, m_listControl);


BOOL CAddDetailsDlg::OnInitDialog()

    CDialogEx::OnInitDialog();
    // TODO:  Add extra initialization here 
    ageSpin=reinterpret_cast<CSpinButtonCtrl*>(GetDlgItem(IDC_AGE_SPIN));   
    ageBuddy=reinterpret_cast<CEdit*>(GetDlgItem(IDC_AGE_BUDDY));   
    ageSpin->SetBuddy((ageBuddy));
    ageSpin->SetRange32(18,60);     
    departmentControl.AddString("Human Resource");
    departmentControl.AddString("Manager");
    departmentControl.AddString("Administrator");
    departmentControl.AddString("Desktop Engineer");

    m_listControl.InsertColumn(0,"ID",0,100);
    m_listControl.InsertColumn(1,"Name",0,100);
    m_listControl.InsertColumn(2,"Age",0,60);
    m_listControl.InsertColumn(3,"Department",0,100);       
    m_listControl.SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT );

    m_ageVariable="18";
    UpdateData(FALSE);

    return TRUE;  // return TRUE unless you set the focus to a control
    // EXCEPTION: OCX Property Pages should return FALSE

void CAddDetailsDlg::OnBnClickedEdit()

    // TODO: Add your control notification handler code here    
    UpdateData();
    if((m_id=="")||(m_name=="")||(m_department=="")||(m_ageVariable==""))
    
        MessageBox("Please choose an item to edit","Error");
    
    else
               
            int index=m_listControl.GetSelectionMark();
            m_listControl.SetItemText(index,0,m_id);
            m_listControl.SetItemText(index,1,m_name);
            m_listControl.SetItemText(index,2,m_ageVariable);
            m_listControl.SetItemText(index,3,m_department);            
            MessageBox("Successfully Updated","Info");       
           

void CAddDetailsDlg::OnBnClickedNewButton()

    // TODO: Add your control notification handler code here    
    UpdateData();
    if((m_id=="")||(m_name=="")||(m_department=="")||(m_ageVariable==""))
    
        MessageBox("Please fill in all the details","Error");
    
    else
           
        int count=m_listControl.GetItemCount();
        count=m_listControl.InsertItem(count,m_id);
        m_listControl.SetItemText(count,1,m_name);
        m_listControl.SetItemText(count,2,m_ageVariable);
        m_listControl.SetItemText(count,3,m_department);        
    

注意:-

如果我只更新 ID,更新功能可以正常工作。如果我尝试更新所有/许多文件,则只有 ID 得到更新,没有别的。顺便说一句,age 是 spinControl,department 是 comboBox,另外两个是 editBox。

编辑:-

我发现变量m_name 的值和editBox 值在m_listControl.SetItemText(index,0,m_id); 行之后都更改为旧值。 m_agem_department 的情况相同。 如果我评论 m_listControl.SetItemText(index,0,m_id); 行,我可以一次更新所有内容,除了 ID

我可以通过将m_namem_agem_department 存储在m_listControl.SetItemText(index,0,m_id); 行之前的局部变量中并在SetItemText() 中使用这些变量来更新所有内容。但随着我的学习,我想知道我哪里错了。

【问题讨论】:

你调试了吗? int index=m_listControl.GetSelectionMark()之后的mindexright的值是多少? 请显示您在“注释”下描述的代码的两个版本。一般在这里提问的时候,不要描述你的代码,展示出来。 @Micheal walz,这是用户在 UI 中执行的两种情况,而不是我的代码的任何单独版本。在调试时,'m_name' 值是正确的值。但在 'm_listControl.SetItemText(index,0,m_id);' 行之后, m_name 采用旧值。我不知道。 请通过编辑您的问题进行解释。 @MichaelWalz,对不起。我的错。我现在更新了问题。 【参考方案1】:

我认为您忘记在 Update_Bn_Click 下的代码之前添加 UpdateData(),因为在我这边,我将您的代码与 updatedata() 一起使用,并且工作正常。

UpdateData();
int index=m_List.GetSelectionMark();
m_List.SetItemText(index,0,m_id);
m_List.SetItemText(index,1,m_Name);
m_List.SetItemText(index,2,m_Age);
m_List.SetItemText(index,3,m_DepartMent);

【讨论】:

我已经试过了。没有任何帮助。不知何故,变量的值和编辑框中的值都更改为旧值(即使我不使用 UpdateData())。我认为问题在于我的更新方式。【参考方案2】:

尝试在更新项目后发送一些消息。

while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))

    TranslateMessage(&msg);
    DispatchMessage(&msg);

【讨论】:

输入随机代码直到一切正常,这不是一个可行的解决方案策略。如果你不能解释,为什么这行得通,它就行不通。 因此,仍有 100 位 MFC 开发人员仍在贡献他们的专业知识。这不是我第一次收到你们 MF 的反对票。我在这里的工作已经完成了。还剩 99 个。 #DarwinAwards *** 与数量无关。这是关于质量的。 三个答案是每个人都可以处理的。提供预感总比没有好——尤其是在涉及相当分散的问题时。顺便说一句:我们仍在等待您的高质量回答......【参考方案3】:

关闭排序。 在您的设计师中: 属性>行为>排序设置为无。

【讨论】:

【参考方案4】:

您必须先将 Item 添加到 0 列索引中。

listcontrol->InsertItem(0,_T("text"));

然后,您可以为子项设置文本;

listctrol->SetItemText(0,1,_T(subText)):

【讨论】:

【参考方案5】:

首先,确保控件的 Owner Data 属性设置为 FALSE。

也许在最后一个SetItemText() 之后尝试m_List.Update(index)

我必须承认,在我需要更新列表元素的任何地方,我都使用所有者数据CListCtrl,因为我认为在大量项目的情况下它更快,并且从长远来看更容易处理。

【讨论】:

什么是“控件的所有者数据属性”CListCtrl::Update 仅在应用程序需要立即强制重绘时使用。添加项目会使控件自动失效,因此无需强制重绘。提议使用虚拟列表控件根本无法解决问题。 转到设计视图,单击 ListCtrl,然后查看控件属性。在那里你可以在某处找到“所有者数据”。 CListCtrl::Update 只是一种预感。我不想提议,只是谦虚地提到我从未尝试过更新非所有者数据 CLIstCtrl,所以如果它不起作用,人们不会将我钉在十字架上——显然是徒劳的...... 是的,它不起作用。但这并不意味着投反对票。 @Hari:您使用的 Visual Studio 版本是什么? 为了确保它不是更新问题,您可以在 SetItemText() 之后调用 GetSubItemRect() 和 InvalidateRect() 吗?

以上是关于MFC CListCtrl::SetItemText() 不工作的主要内容,如果未能解决你的问题,请参考以下文章

在mfc中如何使用按钮依次输入数据

c++ mfc 代码

(转载)DLL动态链接库编程入门之五:MFC扩展DLL

MFC控件消息

VS2010-MFC(MFC常用类:MFC异常处理)

mfc 关于Accept函数