正确的方法来更改VCL组件的内容

Lun*_*din 3 c++ vcl c++builder

我经常在制作VCL程序时遇到这样的情况:

  • 我在表单上有许多组件,允许用户操作.最常见的是一堆编辑框.
  • 当用户手动输入内容时,需要通过OnChange事件验证这些编辑框的内容.
  • 在表单的其他地方,有一些组件可供用户点击以获取一些默认值加载到编辑框中(在TEdit :: Text中).

现在我想要的是,每当用户在TEdit :: Text中输入内容时,OnChange事件必须处理用户输入.但是当我的程序将TEdit :: Text设置为默认值时,这不是必需的,因为我知道该值是正确的.

不幸的是,编写代码myedit->Text = "Default";会触发OnChange事件.

我倾向于用我认为相当丑陋的方法解决这个问题:通过创建一个bool变量is_user_inputTEdit::OnChange检查.如果是,则TEdit :: Text将被验证,否则将被忽略.但是,当然,这并不妨碍程序TEdit::OnChange在不必要时启动.

是否有更好或更清洁的方法来实现这一目标?

有没有办法让OnChange检查谁叫它?或者我想,一种暂时禁用OnChange事件的方法会更好.TEdit::Enabled似乎不会影响是否OnChange被触发.

Rem*_*eau 6

您可以OnChange暂时取消分配事件处理程序:

template <typename T>
void SetControlTextNoChange(T *Control, const String &S)
{
    TNotifyEvent event = Control->OnChange;
    Control->OnChange = NULL;
    try {
        Control->Text = S;
    }
    __finally {
        Control->OnChange = event;
    }
 }
Run Code Online (Sandbox Code Playgroud)

SetControlTextNoChange(myedit, "Default");
Run Code Online (Sandbox Code Playgroud)

或者,RAII适合这种事情:

template <typename T>
class DisableChangeEvent
{
private:
    T *m_control;
    TNotifyEvent m_event;
public:
    DisableChangeEvent(T *control);
    {
        m_control = control;
        m_event = control->OnChange;
        control->OnChange = NULL;
     }

    ~DisableChangeEvent();
    {
        m_control->OnChange = m_event;
    }

    T* operator->() { return m_control; }
};
Run Code Online (Sandbox Code Playgroud)

DisableChangeEvent(myedit)->Text = "Default";
Run Code Online (Sandbox Code Playgroud)