我在做VCL程序的时候经常遇到这样的场景:
- 我在表单上有许多组件,允许用户摆弄。最常见的是一堆编辑框。
- 当用户手动输入内容时,需要通过 OnChange 事件验证这些编辑框的内容。
- 在表单的其他地方,有一些组件,用户可以单击这些组件以将一些默认值加载到编辑框中(在 TEdit::Text 中)。
现在我想要的是,无论何时用户在 TEdit::Text 中键入内容,OnChange 事件都必须处理用户输入。但是当我的程序将 TEdit::Text 设置为默认值时,这不是必需的,因为那时我知道该值是正确的。
不幸的是,编写类似 myedit->Text = "Default";
的代码会触发 OnChange 事件。
我倾向于用一种我认为相当丑陋的方法来解决这个问题:通过创建一个 bool 变量 is_user_input
,TEdit::OnChange
检查它。如果为真,TEdit::Text 将得到验证,否则将被忽略。但当然,这不会阻止程序在不必要时启动 TEdit::OnChange
。
是否有更好或更简洁的方法来实现这一点?
OnChange 有没有办法检查调用者是谁?或者我想,暂时禁用 OnChange 事件的方法会更好。 TEdit::Enabled
似乎不会影响 OnChange
是否被触发。
最佳答案
您可以简单地暂时取消分配 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;
}
}
SetControlTextNoChange(myedit, "Default");
或者,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; }
};
DisableChangeEvent(myedit)->Text = "Default";
关于c++ - 更改 VCL 组件内容的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21673640/