很多时候,当我制作VCL程序时,我遇到了这样的场景:
现在我想要的是每当用户在TEdit :: Text中输入内容时,OnChange事件必须处理用户输入。但是当我的程序将TEdit :: Text设置为默认值时,这不是必需的,因为我知道该值是正确的。
不幸的是,编写像myedit->Text = "Default";
这样的代码会触发OnChange事件。
我倾向于用我认为相当丑陋的方法来解决这个问题:创建一个bool变量is_user_input
,TEdit::OnChange
检查。如果是,则TEdit :: Text将被验证,否则将被忽略。但是,当然,这并不妨碍程序在不必要时启动TEdit::OnChange
。
有更好或更清洁的方法来实现这一目标吗?
OnChange有办法检查是谁调用了它吗?或者我想,一种暂时禁用OnChange事件的方法会更好。 <{1}}似乎不会影响TEdit::Enabled
是否被触发。
答案 0 :(得分: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;
}
}
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";
答案 1 :(得分:0)
OnChange有办法检查是谁调用了它吗?
通常事件有一个参数Sender,你可以在事件函数中检查是否(Sender == ButtonSetDefaults)。不确定如果Button触发OnChange事件并且现在无法测试它会发生什么。
否则我发现除了计时问题之外,全局变量没有问题,但是你也可以遇到那些有禁用事件的问题。