WinForms:响应BindingSource被应用

本文关键字:应用 BindingSource 响应 WinForms | 更新日期: 2023-09-27 18:19:09

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

或者是否存在另一个事件,在该事件中我可以保证数据源已被应用?


我正在使用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事件处理程序。但是,在搜索过程中,我看到没有设置标记值。如果我刚刚设置了数据源,这怎么可能呢?

从我的表单的内部管理代码中可以看出,我已经通过设计器的属性窗口正确地设置了值:

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"; } }
}

WinForms:响应BindingSource被应用

数据绑定应该在表单加载事件之前已经激活。您遇到的问题是,由于数据绑定基础结构优化,在不可见控件第一次变得可见之前,不会对它们进行绑定。这可能是因为WF的设计者认为数据绑定将只用于绑定数据属性(如Text等),而对不可见的控件这样做没有意义。

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

public static class ControlUtils
{
    static readonly Action<Control, bool> CreateControlFunc = (Action<Control, bool>)Delegate.CreateDelegate(typeof(Action<Control, bool>),
        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();
    }
}

然后在表单的开头加上load事件处理程序

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事件。此时,表单正在显示,因此您的所有内容都应该完成并可用。所以,最初的检查是确保它变得可见。如果是,立即从事件处理程序中删除它自己,您只需要执行一次,而不是每次显示/隐藏/显示它…