当Control.Visible == false时,无法将数据绑定到控件

AZ.*_*AZ. 11 c# data-binding winforms

在使用C#4.0/C#2.0的WinForms中,如果控件的可见字段为false,则无法绑定到控件:

this.checkBox_WorkDone.DataBindings.Add("Visible", WorkStatus, "Done");
Run Code Online (Sandbox Code Playgroud)

我可以确认绑定已成功添加到控件的数据绑定列表中,但如果我更改绑定对象(WorkStatus),则不会发生任何事情.

这就是WorkStatus的样子:

public class WorkStatus : INotifyPropertyChanged
{
    private Boolean _done;
    public Boolean Done
    {
        get { return _done; }

        set
        {
            if (_done == value) return;

            _done = value;

            // fire event
            RaisePropertyChanged("Done");
        }
    }

    private Int32 _time;
    public Int32 Time
    {
        get { return _time; }

        set
        {
            if (_time == value) return;

            _time = value;

            // fire event
            RaisePropertyChanged("Time");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChanged(String propertyName)
    {
        OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
    }

    protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        if (PropertyChanged != null) { PropertyChanged(this, e); }
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑
要重现,只需在设计器中设置Visible = false,或在数据绑定之前在构造函数中设置.
使用Add()方法的一个重载也会失败:

this.checkBox_WorkDone.DataBindings.Add("Visible", WorkStatus, "Done",
   true, DataSourceUpdateMode.OnPropertyChanged);
Run Code Online (Sandbox Code Playgroud)

我想隐藏控件的原因是我不希望用户在第一次显示表单时看到控件.

解决方案
谢谢各位,我想我找到了解决方案:

只需在Form.Load()事件中设置Control.Visible = false.在这种情况下,当显示表单时,控件不可见.

虽然,为什么MS以这种方式设计数据绑定仍然是未知数.

Sco*_*ain 12

我之前遇到过这种情况.在控件第一次可行之前,一些后端初始化永远不会发生,初始化的一部分是启用数据绑定.您必须CreateControl(true)在数据绑定工作之前调用.但是,该方法是受保护的方法,因此您必须通过反射或扩展控件来执行此操作.

通过反思:

private static void CreateControl( Control control )
{
    var method = control.GetType().GetMethod( "CreateControl", BindingFlags.Instance | BindingFlags.NonPublic );
    var parameters = method.GetParameters();
    Debug.Assert( parameters.Length == 1, "Looking only for the method with a single parameter" );
    Debug.Assert( parameters[0].ParameterType == typeof ( bool ), "Single parameter is not of type boolean" );

    method.Invoke( control, new object[] { true } );
}
Run Code Online (Sandbox Code Playgroud)

所有事件都将延迟,直到控件Created设置为true.

  • 如果控件在设计器中初始设置为Visible = false,则"DataSourceUpdateMode.OnPropertyChanged"对我不起作用. (3认同)
  • 那么@RitchMelton 当您控制另一个 TabPage 并且不希望事件被推迟时,进行数据绑定的“正确方法”是什么?(请参阅我在答案中链接到的旧 SO 问题,例如代码) (3认同)