【问题标题】:Can I trigger a method by any event of a certain type我可以通过某种类型的任何事件触发方法吗
【发布时间】:2013-06-18 20:40:12
【问题描述】:

我正在构建一个简单的 Windows 窗体应用程序。每次更改控件的值时,控件都会触发将新值发送到对象的事件。

问题是,每次发生这种情况时,我都想将 IsDirty bool 设置为 true。我当然可以在每个事件方法中编写 IsDirty = true,但我想知道是否有更巧妙的方法来执行此操作 - 因为我有大量控件。

我能否将我的 IsDirty=true 代码放在一个方法中,让它在每次触发任何 TextChanged 或 ValueChanged 事件时运行?

【问题讨论】:

  • IsDirtyData 概念,而不是 UI 概念。恐龙 Winform 的问题在于,您永远不会学会将 UI 与数据分开,因此会求助于各种可怕的 hack。而这应该通过在 Model 类中的 OnPropertyChanged() 方法中添加 1 行来解决。
  • @HighCore - IsDirty 不一定是所有情况下的模型概念 - 有时它是一个持久性概念,有时它纯粹是一个 UI 概念。在 OP 的情况下是哪一个尚不清楚。
  • 谢谢 HighCore。我想你只是给了我一个解决方法的想法!我将把 isdirty bool 放在接收数据的对象中。然后在属性更改时将其设置为 true。我同意winforms。我需要学习WPF
  • @lbushkin 你能说出IsDirty 将成为 UI 概念的 1 个案例吗?
  • @HighCore - 您有一个分层合成模型,需要跟踪何时显示表面区域并因此重绘。在这种情况下,“IsDirty”是严格意义上的 UI。

标签: c# windows winforms visual-studio


【解决方案1】:

事件的好处是一次可以订阅多个方法。 您总是可以编写一个特殊的处理程序:

private void UpdateIsDirtyHandler(object sender, EventArgs e)
{
    IsDirty = true;
}

在表单的 Loaded 事件中,遍历所有引发 TextChanged 事件的子控件(TextBoxes、ComboBoxes 等)并将此处理程序附加到它们:

// psuedocode:
foreach( Control ctl in myForm.Controls )
{
    if( ctl is TextBox )
    {
        ((TextBox)ctl).TextChanged += UpdateIsDirtyHandler;
    }
    if( ctl is ComboBox )  { ... }
      // etc...
}

如果您的表单有一组模型对象(这通常是一个很好的做法),您可以在那里处理“脏”跟踪逻辑。脏跟踪并不总是适合您的模型 - 这取决于您的“IsDirty”概念是否仅适用于用户界面或模型。

【讨论】:

  • 谢谢!这是一个很好的解决方案!我现在唯一的问题是,在 Load 事件触发时,表单似乎只有很少的控件。我找不到“已加载”事件,这似乎很合适 - 因为我想在表单完全加载时进行迭代。还是仅仅是因为大多数控件都在组框和选项卡中?
  • 另外,您可以在 Activated 事件中订阅,但您仍然必须递归地探索控件树以订阅所有子控件。
【解决方案2】:

您可以按照here 的描述使用更改的事件。 您可以创建此事件的句柄以将 isDirty bool 设置为 true。

我假设您已经考虑过处理这个 isDirty bool 以及如何将其设置回 false。否则在第一次更改后它仍然是正确的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-07
    • 1970-01-01
    • 2012-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多