I have a global class and an asp.net page. I want use globally declared singleton members without re-declaring the class name.
for example:
Panel.cs:
public class Panel {
public static Panel P = new Panel();
private Panel() {
}
public void DoSomething() {
HttpContext.Current.Response.Write("Everything is OK!");
}
}
sample.aspx.cs:
public partial class temp_sample :System.Web.UI.Page {
Panel p = Panel.P;
protected void Page_Load(object sender, EventArgs e) {
//regular:
myP.DoSomething();
//or simply:
Panel.P.DoSomething();
//it both works, ok
//but i want to use without mentioning 'Panel' in every page
//like this:
P.DoSomething();
}
}
Is this possible? Thank you very much!
Create base class inherited from Page
class MyPage : System.Web.UI.Page
and put your p property there once.
Than just inherit your pages from MyPage instead of System.Web.UI.Page
assuming you're just looking to implement the singleton pattern (avoid scoping a Panel property within each page):
public class Panel
{
#region Singleton Pattern
public static Panel instance = new Panel();
public static Panel Instance
{
get { return instance; }
}
private Panel()
{
}
#endregion
public void DoSomething()
{
HttpContext.Current.Response.Write("Everything is OK!");
}
}
Then reference it simply using:
Panel.Instance.DoSomething();
Related
I made a class which requires the public default constructor but
that is never called; instead another constructor is used at DataGrid.AddingNewItem.
I'd like to tell developers that the default constructor is not for their use.
Is there an attribute which suits the purpose?
I had checked DebuggerNonUserCode and MethodImplAttribute with MethodImplAttributes.InternalCall but not sure that's the proper approach.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.dataGrid1.CanUserAddRows = true;
var list = new List<RowX>();
this.dataGrid1.ItemsSource = CollectionViewSource.GetDefaultView(list);
this.dataGrid1.AddingNewItem += (s, e) => e.NewItem = new RowX("ABC");
}
}
public class RowX
{
public RowX()
{
//this is not used. but CollectionView require this to be public or
//CanUserAddRows doesn't work.
}
public RowX(object o)
{
//this is the actual ctor.
}
public string Text { get; set; }
}
Mark it private
class Foo
{
private Foo() {}
}
You can give your constructor an access modifier.
private This means it can only be called from another constructor in that class.
public class PrivateClass
{
//Only from inside this class:
private PrivateClass()
{
}
public static PrivateClass GetPrivateClass()
{
//This calls the private constructor so you can control exactly what happens
return new PrivateClass();
}
}
internal This means only code in the same assembly (i.e. from inside your library) can access it.
public class InternalClass
{
//Only from within the same assembly
internal InternalClass(string foo)
{
}
}
As the title suggests, I have made/initialized/whatever a 2D list in Class 1, I fill it with stuff in class 2 and am trying to use its contents in class 3.
However, after filling the list in class 2 (where I have confirmed it has been filled), when calling the method in class 3 where the class is to be used, it is simply empty and I have no clue why.
Class 1
class class1
{
public List<List<String>> playerInfo = new List<List<String>>();
//it's a 2D list but as far as I know that shouldn't be a problem
Class 2
public sealed partial class class2: Page
{
class1 host = new class1();
private void joinButton_Click(object sender, RoutedEventArgs e)
{
if (host.playerInfo.Count() <= 4)
{
//fill list
It seems to go OK up to this point. If I do a Count it shows it contains 2 elements, cool.
Class 3
public sealed partial class MainPage : Page
{
GameHost host = new GameHost();
public void Init()
{
if (host.playerInfo.Count() >= 2)
{
//Do stuff
}
}
}
Yet here the list is simply empty. The Count simply returns 0.
What could this be?
If my example here is not very clear, let me know, I'm not very good with this Stack Overflow thing yet.
The problem is that you create a new instance in the MainPage Class. This instance has no values in the list. You could simply pass the instance into the Init method as parameter:
public sealed partial class MainPage : Page
{
public void Init(GameHost host)
{
if (host.playerInfo.Count() >= 2)
{
//Do stuff
}
}
}
If you want to use the GameHost instance throughout the entire MainPage class you can also pass it through the constructor and initialize the field like this:
public sealed partial class MainPage : Page
{
GameHost host;
public MainPage (GameHost _host)
{
host = _host;
}
}
Now it becomes usable in the class with all the initialized values that you had before.
public sealed partial class MainPage : Page
{
GameHost host;
public MainPage (GameHost _host)
{
host = _host;
}
public void Init(GameHost host)
{
if (host.playerInfo.Count() >= 2) // now it should have the desired items
{
//Do stuff
}
}
}
Here's how I would do it.
Initialize 2D List in App.xaml.cs on App Launch
private static List<List<String>> _playerInfo;
public static List<List<String>> PlayerInfo
{
get
{
return (_playerInfo == null) ? new List<List<string>>() : _playerInfo;
}
set { _playerInfo = value; }
}
Now there is no need for class 1.
class2 will be
public sealed partial class class2 : Page
{
private void joinButton_Click(object sender, RoutedEventArgs e)
{
if (App.PlayerInfo.Count <= 4)
{
// Fill your List Here
}
}
}
And MainPage will be
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
if (App.PlayerInfo.Count >=2)
{
// Do Stuff.
}
}
}
Anyway, the common root cause for that is overriding the list reference.
See the simple example below:
static void Main()
{
List<int> mainList = new List<int>();
UpdateList(mainList);
Console.WriteLine(mainList.Count); // prints 0
}
private static void UpdateList(List<int> numbers)
{
numbers = new List<int>();
numbers.Add(1);
numbers.Add(2);
Console.WriteLine(numbers.Count); // prints 2
}
The list reference is transferred in the UpfdateList function. Once you executed the first line in UpfdateList with the new keyword, you lost the reference to the list from the main and now the referrence is to the new list created in UpfdateList.
To fix it, don't override the list reference:
private static void UpdateList(List<int> numbers)
{
//numbers = new List<int>(); remove that
numbers.Add(1);
numbers.Add(2);
Console.WriteLine(numbers.Count); // prints 2. 'numbers' still holds the reference the the list from the main
}
Also, make sure you are using the same instance of Class1 in Class2 and Class3.
I have an application with MainWindow and another class called MyClass. MyClass has a method in it that I need to access from the MainWindow class. MyClass is loaded when the application loads. How do I call the method in MyClass from MainWindow without creating a new instance of MyClass:
MyClass class = new MyClass();
?
The straight forward answer to your question is to mark class method as static. That will allow you calling it from any place.
On the other hand, it's probably is not what you really need. Thus, if you create MyClass on application start inside Application class then you need to expose MyClass instance, for example, through application property. Look at the example code.
public class MyClass
{
public void Method()
{
// ...
}
}
The code of your App:
public partial class App
{
public MyClass MyClassInstance { get; private set; }
private void Application_Startup(object sender, StartupEventArgs e)
{
MyClassInstance = new MyClass();
}
}
And the code of window where you call method of your class:
public partial class MainWindow : Window
{
private void Button_Click(object sender, RoutedEventArgs e)
{
((App)Application.Current).MyClassInstance.Method();
}
}
Sounds very suspect, but you do what you are saying by making that method static
public partial class MainWindow
{
public void MethodInMainWindow()
{
// Don't need to create a new instance of MyClass
MyClass.MethodInMyClass();
}
}
public class MyClass
{
public static void MethodInMyClass()
{
// ....
}
}
Here is a little bit of documentation on static vs instance
I've searched Google all day and can't find the correct answer to my issue, hoping someone here can help me.
So, in the "Main" form I have the method to show a form that needs to be centered directly above the parent form (frmMain). Normally I would call ShowDialog(this) to see the parent, but for some reason I have to set the loadNewsFeedItem to static in order to see the method from the flpNewsFeedHeader : Label derrived class (below). The OnClick event triggers the method loadNewsFeedItem().
When I call this to set the parent, I'm getting the message "Keyword 'this' is not valid in a static property, static method, or static field initializer"
namespace NewsFeeds
{
public partial class FrmMain : Form
{
public static void loadNewsFeedItem()
{
frmNewsFeedView frmFeedView = new frmNewsFeedView(FrmFuncs.selFeedID);
frmFeedView.ShowDialog(this); // Error occurs on this line, when calling this via a static method
}
}
}
public class flpNewsFeedHeader : Label
{
private int FeedID = 0;
public int theFeedID
{
get { return FeedID; }
set { FeedID = value; }
}
protected override void OnClick(EventArgs e)
{
FrmFuncs.selFeedID = FeedID;
Thread thrShowFeed = new Thread(new ThreadStart(FrmMain.loadNewsFeedItem));
thrShowFeed.Start();
}
}
Can someone please give me a corrected code example or a hint as to how to get the loadNewsFeedItem() to be visible without setting the accessor to static, or how to work around this in a static accessor?
Thanks in advance!
Chris
Edit: used ActiveForm for owner.
public partial class FrmMain : Form
{
public static void loadNewsFeedItem(Form owner)
{
frmNewsFeedView frmFeedView = new frmNewsFeedView(FrmFuncs.selFeedID);
frmFeedView.ShowDialog(owner);
}
}
}
public class flpNewsFeedHeader : Label
{
private int FeedID = 0;
public int theFeedID
{
get { return FeedID; }
set { FeedID = value; }
}
protected override void OnClick(EventArgs e)
{
FrmFuncs.selFeedID = FeedID;
// Shouldn't need a new thread. Already on the GUI thread.
FrmMain.loadNewsFeedItem (System.Windows.Forms.Form.ActiveForm);
}
}
may be you mean this:
frmFeedView.Owner = System.Windows.Forms.Form.ActiveForm;
frmFeedView.ShowDialog();
In a static method, this is meaningless. One option is to skip the parameter
frmFeedView.ShowDialog();
The other option is to setup a static variable as shown below (but beware, it can have side effects if you try to open multiple instances of FrmMain)
public partial class FrmMain : Form
{
private static FrmMain staticInstance;
public FrmMain()
{
staticInstance = this;
InitializeComponent();
...
}
public static void loadNewsFeedItem()
{
frmNewsFeedView frmFeedView = new frmNewsFeedView(FrmFuncs.selFeedID);
frmFeedView.ShowDialog(staticInstance );
}
I have a problem in a same namespace:
public partial class frmForm1 : Form // Form1
{
public class Account
{
public string Username, Password, RePassword, Name, bd, dt, dc;
}
public class ListAcc
{
public static int count = 0;
private static List<Account> UserList;
public static List<Account> Data()
{
return UserList;
}
}
public partial class frmForm2 : Form // Form2
{
private void button2_Click(object sender, EventArgs e)
{
ListAcc A; // error
string n = A<Account>[0].Usename; // error
// What should i do?
}
}
Someone can help me fix this problem? Thanks a lot!
You've nested the Account and ListAcc class inside the frmForm1 class.
Move them outside of frmForm1's class definition or change it to be frmForm1.ListAcc A;
Also, I'm not sure what you're trying to do here. This wouldn't compile no matter what you do. Are you trying to make ListAcc a generic class?
string n = A<Account>[0].Usename; // error
If you need Account in more than one class maybe it's better not to put in in the frmForm1 but in a separate file. A class inside another class is not a good idea.
public partial class frmForm1 : Form // Form1
{
public class Account
{
//some code
}
public class ListAcc
{
//SomeCode
}
}
public partial class frmForm2 : Form // Form2
{
private void button2_Click(object sender, EventArgs e)
{
//Thats will work
frmForm1.ListAcc A = new frmForm1.ListAcc();
string n = A.Data()[0].Usename;
}
}
the way your class structure is defined you need to declare the variable like this
frmForm1.ListAcc A;
Move Account class outside the frmForm1 class.
Or you should address your Account type through its "parent" type frmForm1:
frmForm1.Account