好的,这有点抽象,但这里有:
我正在创建一个网站,我希望有一个字段“foo”,我可以从该网站的任何页面访问。我认为最好的方法是创建一个名为“bar”的子类,将受保护的字段“foo”添加到其中,然后将所有网页都放在“bar”中。当当。现在每个页面都有foo。
但现在我将控件添加到我的页面,我希望他们可以访问“foo”。
好吧,现在foo无法受到保护,所以它是公开的。精细。但控件如何知道“foo”?我可以通过在我的控制中执行类似的操作来访问foo:
Foo foo = ((Bar)Page).foo;
这很有效,但让我觉得有点难看。我真的很想能够使用foo。我想,嘿,也许我可以用我为页面做的控件做同样的技巧。我创建了一个新的类,“blargh”继承自UserControl,并以丑陋的方式抓住foo。然后我的控件继承自blargh。耶!
除非它不起作用。当我启动项目时,它会抱怨该行试图访问((Bar)Page).foo,因为Page为null。为什么?页面怎么可能为空?当我看到调用堆栈时,我得不到任何帮助。
有一种简单易懂的方法吗?我吠叫错了树吗?
答案 0 :(得分:2)
如果您需要每个用户拥有自己的实例,您可以将其存储在会话中。
Session["foo"]=data;
然后在您的其他页面上,您可以使用:
Control ctl = (Control) Session["foo"];
请记住,您必须将Session [“foo”]强制转换为您想要使用的任何类型。还有一个类似的Application []空间,如果你只需要为网站的每个用户提供一个实例,就可以使用它。
答案 1 :(得分:2)
在决定哪些对象需要访问以及哪些对象不需要访问之前,另一个简单的入门方法是简单地创建一个公共静态类来保存这个和其他全局对象。类似的东西:
public static class Globals
{
public static Foo foo = new Foo();
}
答案 2 :(得分:1)
您需要访问什么?如果它的数据,为什么不把foo的值放在Session中呢?然后可以从任何地方访问它。
答案 3 :(得分:1)
foo是全局共享的相同值,还是每个页面都有所不同?
我看到你可能会喜欢的两种可能性:
把它放到ASP.Net的Application对象中(我不记得它在asp.net中的确切位置,但是使用该名称可以在其上找到doc)。这将是一个不变的全球价值。
将其设为Control的扩展方法。页面最终继承自Control,因此它将可用。像这样:
public static class ControlExtensions
{
public static Foo foo(this Control self)
{
return foo;
}
}
现在UserControls和Pages应该可以访问它。
答案 4 :(得分:1)
要查看的一个选项是使用extension methods
扩展页面类只要有一个Page实例,Page就会有Foo可用。根据Foo的工作情况,您可能仍需要将数据存储在会话中。
至于为何您的控件无法使用Page。只有在将控件添加到页面后,才会填充Page属性。如果您的控件没有直接位于页面上,那么当它位于页面上的anscetor被添加到页面时。
答案 5 :(得分:1)
您必须确定此[foo]对所有用户是否相同,或者是否特定于单个用户。如果它对所有人都一样,带静态变量的静态类将为你解决这个问题。
public static class FooClass {
public FooClass() {
}
public static string FooName = "TheFoo";
}
如果您正在查看每个用户特定的内容,我建议使用Session来存储它。你也可以把你的FooClass放到会话中,它真的取决于你放在那里的东西。
FooClass myFoo = Session["CurrentFoo"] as FooClass;