【问题标题】:Initializing Form Controls初始化表单控件
【发布时间】:2014-01-27 11:38:46
【问题描述】:

我的程序中有一个对话框,用户可以在其中更改某些设置。关闭表单后,更改将存储在应用程序的设置文件中。

每次加载对话框时,设置都会在表单的构造函数中恢复。这就产生了一个问题:CheckedChanged 事件(以复选框为例)将始终在表单完全打开时触发,而无需用户执行任何操作!

我还没有尝试过,但我猜想解决这个问题的一种方法是在数据->应用程序设置下拉取设计器中控件的初始状态。但是这种方法需要为每个控件单独设置 - 由于大量控件是一个问题,因此不实用。

有没有(更好的)方法可以在不触发CheckedChange 事件的情况下预初始化表单上的控件?

【问题讨论】:

    标签: c# initialization controls


    【解决方案1】:

    您可以创建一个名为IsFormLoading 的类级别变量。在构造函数开始时将其设置为 True,然后在所有控件已初始化并恢复设置后将其设置为 False。

    表单上您不想被触发的每个事件都可以检查if (IsFormLoading)return;

    【讨论】:

    • 最好希望在设置该变量之间没有异步发生。否则,该标志将变得毫无用处。
    • @Grant:我尝试了您的解决方案,它运行良好,并且只需要对代码进行最少的更改。竖起大拇指。
    【解决方案2】:

    我假设您在 InitializeComponent() 方法中有事件订阅,如下行:

    private void InitializeComponent() {
      ...
      this.checkBox1.CheckedChanged += new System.EventHandler(this.checkBox1_CheckedChanged);
      ...
    }
    

    并且您在构造函数中调用 InitializeComponent() 方法后恢复了表单的设置。

    如果是这样,为什么不在使用您保存的设置完全初始化所有控件后尝试推迟事件订阅。从InitializeComponent() 中移除所有事件订阅(Event += Handler),并在设置恢复后放置。

    class Form1 : Form {
      public Form1() {
        InitializeComponent(); // remove event subscriptions from InitializeComponent
        ApplySettings();  // restore settings
        AttachEventHandlers(); // subscribe to events here
      }
    }
    

    【讨论】:

    • 你的假设是正确的。这个解决方案可能是最强大的,但对于我需要的东西来说有点过分了。绝对是严肃项目的好方法。
    【解决方案3】:

    所以基本的概述是弹出显示,用户选中一些框,关闭表单,然后保存更改对吗?

    第一个问题:如果您只是保存控件的当前状态(选中、未选中等),为什么还要处理 CheckedChange 事件?为什么不将控件的所有值保存在 Form.FormClosing 事件中?我的意思是我知道调用 changed 事件是因为您在表单加载事件中设置值控件,但是为什么要打扰 changed 事件,除非您在触发 change 事件时正在做某事??

    如果您确实想使用 CheckedChange 事件来执行某些操作,那么您可以使用像这样的计数器(我的头顶代码可能有点错误):

     private int _loadCount;
    
    private void Form1_Load(object sender, System.EventArgs e)
    {
         _loadCount = 0;
         //Code to load values for controls...
    }
    
    
    private void CheckBox1_CheckedChanged(Object sender, EventArgs e) 
    {
       _loadCount++;
       if(_loadCount > 1)
      {
       //Do something here...
      }
      else
      {
       //Do nothing, return false, etc...
      }
    
    }
    

    在任何情况下,无论控件值如何更改(用户单击、通过代码等),AFAIK 控件更改事件总是会触发。

    【讨论】:

    • 是的,这行得通。但我认为这是格兰特早些时候提出的一个主题的变体。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-31
    • 1970-01-01
    • 2019-03-06
    • 2016-08-16
    • 1970-01-01
    • 1970-01-01
    • 2019-07-06
    相关资源
    最近更新 更多