WinForms:响应正在应用的BindingSource

是否有一个事件可以锁定,以便在数据源应用于其绑定控件时得到通知?

还是有另一个事件,我保证数据源已被应用?


我正在使用WinForms(来自WPF)并使用带有数据绑定值的标签,以确定我正在使用的控件类型。 许多控件可以具有相同的标记值,并且我必须使用所需的标记检索控件以执行业务逻辑。

问题是我不知道何时执行搜索标记值。 我在调用后尝试立即搜索标记值:

myBindingSource.DataSource = OutputFunctions.Instance; //Yes... I'm binding to a singleton with a list of properties. //Its not the best method, but works. 

在我的Form.Load事件处理程序中。 但是,在搜索过程中,我看到标签值未设置。 如果我只是设置数据源,那该怎么办?

从我的表单的内部托管代码隐藏可以看出,我已通过设计器的Property窗口正确设置了值:

 this.textBoxDTemp.DataBindings.Add(new System.Windows.Forms.Binding( "Tag", this.myBindingSource, "KNOB_DRIVER_TEMP", true)); 

我已经看过BindingComplete ,老实说看起来非常有前途,除了它在绑定初始化期间没有触发,即使该值应该从数据源传播到目标控件。

编辑:根据要求,数据源首先在表单的内部代码隐藏中设置如下:

 this.myBindingSource.DataSource = typeof(OutputFunctions); 

如果它有帮助,这里是单身人士。

 public class OutputFunctions { private static OutputFunctions instance; public static OutputFunctions Instance { get { if (instance == null) { instance = new OutputFunctions(); } return instance; } } private OutputFunctions() { } public string KNOB_DRIVER_TEMP { get { return "KNOB_DRIVER_TEMP"; } } public string KNOB_PASSENGER_TEMP { get { return "KNOB_PASSENGER_TEMP"; } } public string KNOB_FAN { get { return "KNOB_FAN"; } } } 

应该在表单加载事件之前激活数据绑定。 您遇到的问题是,由于数据绑定基础结构优化,对于不可见控件的绑定不会发生,直到它们第一次可见。 这可能是因为WF的设计者认为数据绑定将仅用于绑定数据属性(如Text等),并且对于不可见控件执行此操作没有意义。

如果你不害怕使用一些内部(或者用户HighCore会说hacks),那么下面的帮助将有助于解决你的问题(我们使用类似的东西多年):

 public static class ControlUtils { static readonly Action CreateControlFunc = (Action)Delegate.CreateDelegate(typeof(Action), typeof(Control).GetMethod("CreateControl", BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(bool) }, null)); public static void CreateControls(this Control target) { if (!target.Created) CreateControlFunc(target, true); else for (int i = 0; i < target.Controls.Count; i++) target.Controls[i].CreateControls(); } } 

并只是放在表单加载事件处理程序的开头

 this.CreateControls(); 

我认为你正在寻找控制器

“BindingContextChanged”事件。

你是否试图在绑定发生时强制添加一些钩子?

由于您正在查看整个表单准备好并建立绑定后,您可能会挂钩到“LOAD”事件。 表单首先准备好所有内容,然后调用“Load”事件。 如果订阅(收听)任何内容,将通知他们。 一旦调用它,您就可以运行并遍历表单上的所有控件并查找任何部件/组件/标签/控件类型等。

  public Form1() { InitializeComponent(); this.VisibleChanged += Form1_VisibleChanged; } void Form1_VisibleChanged(object sender, EventArgs e) { if (!this.Visible) return; // Disable the event hook, we only need it once. this.VisibleChanged -= Form1_VisibleChanged; StringBuilder sb = new StringBuilder(); foreach (Control c in this.Controls) sb.AppendLine(c.Name); } 

编辑每条评论。 我从LOAD事件变为VISIBILITY事件。 此时,表单现在正在显示,因此您的所有内容应该完成并可用。 因此,初步检查是为了确保它变得可见。 如果是这样,立即将其自身从事件处理程序中删除,您只需要执行一次而不是每次可能显示/隐藏/显示它…