我有一个项目,该项目将创建(静态)库的功能委托给该项目? 我所有其他项目中使用的类。 在这些情况下,通过解决方案进行引用。

例如,我有一个扩展,可以在给定的GroupBox面板中创建复选框,并且效果很好:

public static void PreencheCheckboxesPanel(this Panel p, List<CheckBox> listaCheckBoxs) {
    var count = 0;
    listaCheckBoxs.ForEach(
        i => {
            i.Location = new Point(10, 10 + ((count) * 25)); //"dynamic" and not-so-effective resizing here
            i.AutoSize = true;
            count++;
        });
    p.Controls.AddRange(listaCheckBoxs.ToArray());
}}

问题是,我需要在列表顶部插入一个静态复选框,这将收到(取消)检查以下所有复选框的方法。 所以我的代码将成为

internal static CheckBox CKB_ancora = new CheckBox(){};
public static void PreencheCheckboxesPanel(this Panel p, List<CheckBox> listaCheckBoxs) {
    var count = 0;
    if (adicionaAncora) {
        CKB_ancora.Text = textoAncora;
        CKB_ancora.CheckedChanged += (sender, args) => {
            ChecaCheckBoxes(p, CKB_ancora.Checked);
        };
        listaCheckBoxs.Insert(0, CKB_ancora);
    }
    listaCheckBoxs.ForEach(
        i => {
            i.Location = new Point(10, 10 + ((count) * 25)); //"dynamic" and not-so-effective resizing here
            i.AutoSize = true;
            count++;
        });
    p.Controls.AddRange(listaCheckBoxs.ToArray());
}}

其中ChecaCheckBoxes是另一个

public static void ChecaCheckBoxes(this Panel b, bool checkStatus = true) {
    var listaCheckBoxs = (from Control c in b.Controls where c is CheckBox select (CheckBox)c).ToList();
    listaCheckBoxs.ForEach(
        i => {
            i.Checked = checkStatus;
        });
}

CKB_ancora必须是解决方案范围内公认的对象。

原因? 我还有一个名为GetSelectedCheckBoxes扩展,它将用于返回组框中的所有选中的... ah ...复选框。 并且,为了确保“锚点”(我这样称呼它,因为我没有名称(un)?全选复选框)也不会被返回。

如果我运行此代码,它将编译,但是...将在Application.SetCompatibleTextRenderingDefault上的InvalidOperationException上运行,就在Main();上。 显然,在此方法在mainpoint上运行之前无法创建/实例化控件, 这是“ static”的确切定义

问题:知道我需要一种在整个解决方案范围内都可以看到此特定检查的方法...我该怎么做?

#1楼 票数:2

不幸的是,您没有提供一个很好的, 最少的完整的代码示例 ,并且缺少足够的上下文,因此很难提供好的,具体的建议。

就是说,似乎在您这个静态类中的某个地方,您有一个名为CKB_ancora的字段,并且您可能正在使用字段初始化程序对其进行初始化,可能是这样的:

private CheckBox CKB_ancora = new Checkbox();

完成此操作后,您发现在初始化类时(通常是在第一次在运行时访问类中的某些内容时),这种情况发生得太早了,并引发了异常。

假设这是正确的,那么在我看来,最明显,最简单的“修复”方法就是延迟初始化对象。 例如:

private Lazy<CheckBox> _ckb_ancora =
    new Lazy<CheckBox>(() => new CheckBox());

private CheckBox CKB_ancora { get { return _ckb_ancora.Value; } }

这会将对象存储包装在一个属性中,该属性随后使用Lazy<T>的实例将初始化推迟到第一次任何代码实际尝试访问它时进行。


现在,这就是说,我不十分喜欢您的方法,因为在某些实例化对象中使用了静态成员。 如果使用您的库的某人想要将代码与两个或多个Panel实例一起使用怎么办? 一个Control (包括一个CheckBox )不能一次是多个其他Control的子Control ,因此拥有一个静态的Control实例只是行不通的。

恕我直言,最好使用某些识别功能(例如CheckBoxNameTag属性)来适当地处理控件(例如,将其从枚举中筛选出来)。

例如:

public static void PreencheCheckboxesPanel(this Panel p, List<CheckBox> listaCheckBoxs) {
    var count = 0;
    if (adicionaAncora) {
        CheckBox CKB_ancora = new CheckBox();

        CKB_ancora.Text = textoAncora;
        CKB_ancora.Name = "CKB_ancora";
        CKB_ancora.CheckedChanged += (sender, args) => {
            ChecaCheckBoxes(p, CKB_ancora.Checked);
        };
        listaCheckBoxs.Insert(0, CKB_ancora);
    }
    listaCheckBoxs.ForEach(
        i => {
            i.Location = new Point(10, 10 + ((count) * 25)); //"dynamic" and not-so-effective resizing here
            i.AutoSize = true;
            count++;
        });
    p.Controls.AddRange(listaCheckBoxs.ToArray());
}}

并且,例如:

public static void ChecaCheckBoxes(this Panel b, bool checkStatus = true) {
    var listaCheckBoxs = b.Controls
        .OfType<CheckBox>().Where(c => c.Name != "CKB_ancora").ToList();

    listaCheckBoxs.ForEach(
        i => {
            i.Checked = checkStatus;
        });
}

这样,当您检索CheckBox控件列表时,将忽略在开始时添加的特殊控件。


即使这样,我仍然认为代码仍然很脆弱。 上面的方法会更好,但是恕我直言,如果您一开始没有为所有这些方法使用静态成员,那么它可能会更好。 即,相反,您应该设计一种机制,该机制允许您将帮助程序类的实例与其所帮助的Panel对象相关联,以便实际上您可以初始化和存储每个实例的信息,而不会遇到执行顺序问题,例如以及只有一个客户端使用代码的限制。

没有更好的代码示例,尽管如此,我仍然看不到任何提供任何具体建议的好方法。

  ask by Eric Wu translate from so

未解决问题?本站智能推荐:

2回复

无法将我的UserControl转换为Windows.Forms.Control

我尝试在WPF应用程序中使用Acrobat PDF Reader,但是我发现WindowsFormsHost是WinForm控件...因此它可能是问题的根源...我收到消息“无法将OphtalBox.PDFReader转换为Windows.Forms。控制”。 谢谢 我混合了这两个教程:
1回复

重写OnPaint对于Windows.Forms.Control闪烁?

我创建一个新的控件并覆盖了OnPaint事件: 问题是,当我要更换弹药时,所有控件都会弹起。 看起来不太好。 无论如何使我在这条线上画出的线: 弹药改变时只是消失?
3回复

Windows.Forms.Control的具有TabStop和键事件的派生类

我有一个从Forms.Control派生的控件,它可以很好地处理鼠标事件和绘画事件,但是按键事件有问题。 我需要处理向左箭头和向右箭头,但是到目前为止,包含我的课程的Tab控件都吃掉了这些。 如何使该控件具有选择性,针对性?
2回复

将Windows.Controls.UserControl转换为Windows.Forms.Control

我们可以将WPF用户控件转换为表单控件吗?
1回复

什么用于System.Windows.Forms.Control.ControlCollection中的键?

因此, System.Windows.Forms.Control具有Control.ControlCollection类型的Controls属性。 我在一个表单上有一个控件,在这个集合中有一堆小的子控件。 这些子控件具有标签和文本标识符,它是数据库中的字段名称。 我需要能够返回到Cont
3回复

ProductName隐藏System.Windows.Forms.Control.ProductName

我的表单中有一个属性ProductName。 我在编译代码时收到警告。 FormInventory.ProductName隐藏继承的成员' System.Windows.Forms.Control.ProductName' 。 如果要隐藏,请使用new关键字。 下面是我的代码 t
1回复

以编程方式触发System.Windows.Forms.Control事件

假设我有一个Checkbox控件: 如何以编程方式触发此事件? 我可以 但这很丑陋,会触发两次...
1回复

System.Windows.Forms.Control是否不包含“GetEnumerator”公共定义?

当我想遍历Forms控件时,此foreach语句( foreach (Control __control in _control) )给出错误: System.Windows.Forms.Control不包含“ GetEnumerator”公共定义。因此,foreach语句不能为“ Sys