我有一个项目,我委托创建(静态)库的功能?我所有其他项目中使用的类。在这些情况下,它通过解决方案引用。
例如,我有一个扩展程序,可以在给定的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());
}}
问题是,我需要在列表顶部插入一个静态复选框,它会收到一个方法(un)?检查下面的所有复选框。 所以我的代码将成为
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 ...复选框。并且,为了确保&#34;锚定#34; (我称之为,因为我没有(un)?check-all复选框的名称)也不会被退回。
如果我运行此代码,它将进行编译,但是......将在Application.SetCompatibleTextRenderingDefault上运行InvalidOperationException,就在Main();显然,在mainpoint上运行此方法之前无法创建/即时控件,这是&#34; static&#34; 的确切定义。
问题:知道我需要一种方法来保持这个特定的检查解决方案范围可见...我该怎么做?
答案 0 :(得分:2)
不幸的是,你没有提供a good, minimal, complete code example,而且缺乏足够的背景,很难提供好的,具体的建议。
那就是说,似乎在你的这个静态类的某个地方,你有一个名为CKB_ancora
的字段,你可能正在使用字段初始值设定项初始化它,可能是这样的:
private CheckBox CKB_ancora = new Checkbox();
完成此操作后,您发现当初始化类时(通常在第一次运行时访问类中的某些内容时),这种情况发生得太快而引发异常。
假设这是正确的,那么在我看来,最明显和最简单的&#34;修复&#34;是懒惰地初始化对象。例如:
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
的单个静态实例只是不会起作用。
恕我直言,最好使用一些识别功能,例如Name
的{{1}}或Tag
属性来适当地处理控件(例如将其过滤掉) (枚举)。
例如:
CheckBox
并且,例如:
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
对象相关联,这样您实际上可以初始化和存储每个-instance信息,不会遇到执行顺序问题,以及仅使用单个客户端的代码使用限制。
如果没有更好的代码示例,我也没有看到任何提供任何特定建议的好方法。