【问题标题】:CEdit numeric validation event C++ MFCCEdit 数字验证事件 C++ MFC
【发布时间】:2010-10-19 03:36:09
【问题描述】:

我有一个 CEdit 文本框,它是属性窗格的一部分,只允许使用数值(正整数)。当人们输入非数字值时,该框可以正常工作,但是当他们删除框中的值时,会弹出一个对话框说: "请输入一个正整数。"

情况如下:
1. 盒子里有一个数字(比如 20)。
2.我把号码删了。
3. 我收到错误对话框。
谁能告诉我如何拦截此事件并在其中设置默认值?

这是我的属性窗格的样子:


const int DEFAULT_VALUE = 20;

class MyPropertyPane:public CPropertyPane
{
    //....
private:
    CEdit m_NumericBox;
    int   m_value;

    //....
public:
    afx_msg void OnEnChangeNumericBox();

    //....
}
void MyPropertyPane::MyPropertyPane()
{
   // Set a default value
   m_value = DEFAULT_VALUE;
}

//....
void MyPropertyPane::DoDataExchange(CDataExchange* pDX)
{
    DDX_Control(pDX, IDC_NUMERIC_BOX, m_NumericBox);

    // this sets the displayed value to 20
    DDX_Text(pDX, IDC_NUMERIC_BOX, m_value);
}

//....
void MyPropertyPane::OnEnChangeNumericBox()
{
    // Somebody deleted the value in the box and I got an event
    // saying that the value is changed.

    // I try to get the value from the box by updating my data
    UpdateData(TRUE);

    // m_value is still 20 although the value is 
    // deleted inside the text box.
}

【问题讨论】:

    标签: c++ events mfc numeric cedit


    【解决方案1】:

    您收到的消息来自数据验证例程,而不是数据交换例程。 DoDataExchange() 中可能有这样的调用:

    void MyPropertyPane::DoDataExchange(CDataExchange* pDX)
    {
        DDX_Control(pDX, IDC_NUMERIC_BOX, m_NumericBox);
        DDX_Text(pDX, IDC_NUMERIC_BOX, m_value);
        DDV_MinMaxInt(pDX, m_value, 1, 20); // if the value in m_value is outside the range 1-20, MFC will pop up an error dialog
    }
    

    您可以通过删除内置的 MFC 数据验证并添加自己的来解决此问题:

    void MyPropertyPane::DoDataExchange(CDataExchange* pDX)
    {
        DDX_Control(pDX, IDC_NUMERIC_BOX, m_NumericBox);
        DDX_Text(pDX, IDC_NUMERIC_BOX, m_value);
    
        if( m_value < 1 || m_value > 20 )
        {
            m_value = DefaultValue;
        }
    }
    

    【讨论】:

    • 但是 m_value 即使在被删除后仍然是 20...所以检查 m_value
    • 实际上更正.. 在 DoDataExchange 中它甚至没有通过 DDX_Text(pDX, IDC_NUMERIC_BOX, m_value) 所以它甚至不会达到验证码。
    【解决方案2】:

    John Dibling 的提示让我找到了这个解决方案:

    
    void MyPropertyPane::OnEnChangeNumericBox()
    {
        UpdateData(TRUE);
        CString value;
        m_NumericBox.GetWindowText(value);
        if( value.IsEmpty() )
        {
            m_value = DEFAULT_VALUE;
            UpdateData(FALSE);
        }
    }
    

    我真正需要做的唯一验证是检查该框是否包含一个值,因为实际的数字验证已由该框处理。用户不能输入非数字值,但他们可以删除现有的值,因此这是数据交换功能中难以处理的情况,我不得不“破解” OnChange 事件。

    【讨论】:

    • 这在许多情况下都有效,但通常最好在 DoDataExchange() 函数中进行所有数据交换和验证,因为 OnEnChangeNumericBox() 可能不是唯一更改 m_value 的地方。例如,如果您有一个将 m_value 更改为预设值的单选按钮。
    • 好点,一般来说,DoDataExchange() 函数可能是进行验证的最佳位置...我的示例有点例外。
    【解决方案3】:

    这个对我有用

    void CtimersDlg::OnEnChangeInterval()
    {
       CString value; //or use char *
       CWnd *pWnd = GetDlgItem(IDC_INTERVAL);//IDC_EDITBOX
    
       if(pWnd)
       {
          pWnd->GetWindowTextW(value);
       }
    
       int i = _wtoi(value); //if char * use _atol()
       if((!value.IsEmpty())&& (i))  //To check i = 0 or 00 entered or not
          UpdateData(TRUE);
    }
    

    【讨论】:

    • 用户如何输入0?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多