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

时间:2014-02-10 09:43:51

标签: c++ c++builder vcl

很多时候,当我制作VCL程序时,我遇到了这样的场景:

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

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

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

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

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

OnChange有办法检查是谁调用了它吗?或者我想,一种暂时禁用OnChange事件的方法会更好。 <{1}}似乎不会影响TEdit::Enabled是否被触发。

2 个答案:

答案 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事件并且现在无法测试它会发生什么。

否则我发现除了计时问题之外,全局变量没有问题,但是你也可以遇到那些有禁用事件的问题。

相关问题