查看here,它提供了有关标准对话数据验证例程的信息。
我对这个感兴趣:
DDV_MinMaxInt
验证给定的控制值是否超过给定的int
范围。
现在,当您查看here时,它指出:
对话框数据验证(DDV)是一种在对话框中验证数据输入的简便方法。要在对话框中利用DDX和DDV,请使用添加成员变量向导来创建数据成员并设置其数据类型并指定验证规则。
我意识到在最新版本的VS2017中,MFC向导已被限制,并且它将在预览版4中得到解决。这是一个副作用。
我理解它在实践中是如何运作的:
DDV_MinMaxInt(pDX, m_iEventTypeMWB, 1, 4);
问题是,基于对话框上的另一个设置,我有4个不同的范围。它们都从1开始。目前我没有使用DDV,我正在手动测试,如下所示:
void CSpecialEventManagerDlg::OnCbnEditchangeComboboxexReminderInterval()
{
BOOL bEnableOK = TRUE;
UpdateData(TRUE);
SetEventModified();
m_iReminderInterval = static_cast<int>(GetDlgItemInt(IDC_COMBOBOXEX_REMINDER_INTERVAL, nullptr, FALSE));
if (m_iReminderInterval < 1)
bEnableOK = FALSE;
else
{
// The interval can be four weeks (4)
// The interval can be four weeks of days (28)
// The interval can be four weeks of hours (672)
// The interval can be four weeks of minutes (40320)
if ((m_iReminderUnitType == CCalendarSettingsGooglePage::ReminderUnitType::Weeks && m_iReminderInterval > 4) ||
(m_iReminderUnitType == CCalendarSettingsGooglePage::ReminderUnitType::Days && m_iReminderInterval > 28) ||
(m_iReminderUnitType == CCalendarSettingsGooglePage::ReminderUnitType::Hours && m_iReminderInterval > 672) ||
(m_iReminderUnitType == CCalendarSettingsGooglePage::ReminderUnitType::Minutes && m_iReminderInterval > 40320))
{
bEnableOK = FALSE;
}
}
SetCorrectButtonStates();
// Override - we can only apply the changes if the value is OK.
m_btnApplyChanges.EnableWindow(bEnableOK);
}
工作正常。我的问题是:是否可以将运行时的DDV最小/最大范围更改为不同的值集?这样我就可以使用DDV而不是我自己的测试。
我试图摆弄DoDataExchange
以确定我是否可以这样做,但是当我不期待它时,它会显示一个弹出窗口。
这是另一回事:
上面的视觉效果非常好。如果用户键入非数字值,则会显示有用的工具提示。
但是对于DDV,除了多次显示弹出窗口外,它甚至无法指出与之相关的控件。
这是现有的DDX方法(没有任何min / max尝试):
void CSpecialEventManagerDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CSpecialEventManagerDlg)
DDX_Control(pDX, IDC_BUTTON_CLOSE, m_btnClose);
DDX_Control(pDX, IDCANCEL, m_btnCancel);
DDX_Control(pDX, IDC_EDIT_EVENT, m_editEvent);
DDX_Control(pDX, IDC_DTP_EVENT, m_dtpEvent);
DDX_Control(pDX, IDC_LIST_EVENTS, m_lbEvents);
DDX_Control(pDX, IDC_BUTTON_DELETE_EVENT, m_btnDeleteEvent);
DDX_Control(pDX, IDC_BUTTON_ADD_EVENT, m_btnAddEvent);
DDX_Control(pDX, IDC_BUTTON_APPLY, m_btnApplyChanges);
DDX_Control(pDX, IDC_BUTTON_CANCEL_CHANGES, m_btnCancelChanges);
DDX_DateTimeCtrl(pDX, IDC_DTP_EVENT, m_datEvent);
DDX_Text(pDX, IDC_EDIT_EVENT, m_strEvent);
//}}AFX_DATA_MAP
DDX_Control(pDX, IDC_COMBO_EVENT_LOCATION, m_dynEventLocation);
DDX_CBString(pDX, IDC_COMBO_EVENT_LOCATION, m_strLocation);
DDX_Radio(pDX, IDC_RADIO_SRR_INCLUDE_AS_MEETING, m_iEventTypeSRR);
DDX_Radio(pDX, IDC_RADIO_SMR_INCLUDE_AS_MEETING, m_iEventTypeMWB);
DDX_Control(pDX, IDC_DTP_EVENT_START, m_dtEventStartTime);
DDX_DateTimeCtrl(pDX, IDC_DTP_EVENT_START, m_datEventStartTime);
DDX_Control(pDX, IDC_DTP_EVENT_FINISH, m_dtEventFinishTime);
DDX_DateTimeCtrl(pDX, IDC_DTP_EVENT_FINISH, m_datEventFinishTime);
DDX_Check(pDX, IDC_CHECK_EVENT_ALL_DAY, m_bEventAllDay);
DDX_Check(pDX, IDC_CHECK_SET_REMINDER, m_bSetReminder);
DDX_CBIndex(pDX, IDC_COMBO_REMINDER_UNIT, m_iReminderUnitType);
DDX_Control(pDX, IDC_COMBO_REMINDER_UNIT, m_cbReminderUnitType);
DDX_Control(pDX, IDC_COMBOBOXEX_REMINDER_INTERVAL, m_cbReminderInterval);
DDX_Control(pDX, IDC_STATIC_EVENT_START_TIME, m_lblEventStartTime);
DDX_Control(pDX, IDC_STATIC_EVENT_END_TIME, m_lblEventFinishTime);
DDX_Control(pDX, IDC_CHECK_EVENT_ALL_DAY, m_checkEventAllDay);
DDX_Control(pDX, IDC_CHECK_SET_REMINDER, m_checkSetReminder);
}
答案 0 :(得分:4)
在DoDataExchange
:
DDX_CBIndex(pDX, IDC_COMBO_REMINDER_UNIT, m_iReminderUnitType);
DDX_CBIndex(pDX, IDC_COMBOBOXEX_REMINDER_INTERVAL, m_iReminderInterval);
if (m_iReminderUnitType == Weeks)
{
DDV_MinMaxInt(pDX, m_iReminderInterval, 1, 4);
}
else if (m_iReminderUnitType == Days)
{
DDV_MinMaxInt(pDX, m_iReminderInterval, 1, 28);
}
// etc
我调整了我的组合处理程序:
void CSpecialEventManagerDlg::OnCbnEditchangeComboboxexReminderInterval()
{
m_iReminderInterval = static_cast<int>(GetDlgItemInt(IDC_COMBOBOXEX_REMINDER_INTERVAL, nullptr, FALSE));
BOOL bEnableOK = UpdateData(TRUE);
SetEventModified();
SetCorrectButtonStates();
m_btnApplyChanges.EnableWindow(bEnableOK);
}
主要的是我必须在GetDlgItemInt
来电之前致电UpdateData
。然后,在DoDataExchange
:
// Use DDV instead to validate the interval
DDV_MinMaxInt(pDX, m_iReminderInterval, 1, m_iMaxReminderInterval);
这非常有用,因为当用户更改间隔类型时,我已经计算了m_iMaxReminderInterval
: