CComboBox DDX_CBString行为令人困惑

时间:2016-03-15 16:21:34

标签: mfc

我在对话框中使用ComboBox控件为用户提供一些有用的值(例如:10; 20; 100; 400; 800)但是如果需要,让用户插入确切的值。

经过很长时间后我发现了什么: 如果我在Combobox中键入值 40 ,则在UpdataData()始终 400 之后,Combobox会返回。 :(( 如果值 39 41 ,则没有问题。

这不是我和用户所期望的行为 当我输入一个值时,ComboBox应该取这个值,如果从下拉列表中选择Menue,则取此值。

我现在看到这种行为是由DDX_CBString给出的。

我是否必须编写自己的DDX_CBString,还是有另一种方法?

代码:

void CTestDialog::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_IFBANDWIDTH, m_cIFBandWidth);
    DDX_CBString(pDX, IDC_IFBANDWIDTH, m_sIFBandWidth);  // Bahavior confusing
}

BOOL CTestDialog::OnInitDialog()
{
    CDialogEx::OnInitDialog();

    m_cIFBandWidth.ResetContent();

    m_cIFBandWidth.AddString(_T("10"));
    m_cIFBandWidth.AddString(_T("20"));
    m_cIFBandWidth.AddString(_T("100"));
    m_cIFBandWidth.AddString(_T("400"));
    m_cIFBandWidth.AddString(_T("800"));


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

void CTestDialog::OnBnClickedApply()
{   
    UpdateData(TRUE);     // m_sIFBandWidth now 4 ok!
    UpdateData(FALSE);    // m_sIFBandWidth still 4, but control show 400, so the next OnOk() or Apply() take this value. Wrong!
}

2 个答案:

答案 0 :(得分:2)

我通过修改DDX_CBtring解决了这个问题。

void DDX_CBString_Normal(CDataExchange* pDX, int nIDC, CString& value)
{
    ..    
    if (pDX->m_bSaveAndValidate)
    {
        ..      
    }
    else
    {
        // Behaviour as we expect: Type a value and keep it
        // Select it form dropwon, or take the value the user type it
        AfxSetWindowText(hWndCtrl, value);
        return; 

        /* Disable original MS behavior 
        // set current selection based on model string
        if (::SendMessage(hWndCtrl, CB_SELECTSTRING, (WPARAM)-1,
            (LPARAM)(LPCTSTR)value) == CB_ERR)
        {
            // just set the edit text (will be ignored if DROPDOWNLIST)
            AfxSetWindowText(hWndCtrl, value);
        } 
       */
    }
}

如果有人有另一个方法,请告诉我。

答案 1 :(得分:0)

旧问题的新答案:您不必编写自己的DDX处理程序,但这不是错误。 DDX_CBString故意进行部分字符串比较,而提供DDX_CBStringExact进行精确的字符串比较。 MSDN docs对差异的解释不是很明确,所以我同意这一点令人困惑。

您只需手动将行更改为:

DDX_CBStringExact(pDX, IDC_IFBANDWIDTH, m_sIFBandWidth);