我在对话框中使用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!
}
答案 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);