Accessing Non Static Method from another page - c#

I have this in a toggle switch event
LevelPage.change_color() = this.ChangeColorToggle.IsOn;
I am pulling a method with the following code from another page, named LevelPage
Moving_Ellipse.Fill = new SolidColorBrush(Colors.Black);
I want the toggle switch even handler to access the method, but it would say that it needs an object for a non-static method. I am pretty new to this stuff, can anyone help me?

Static vs. Instance
class Human {
public static readonly string SpeciesName = "Homo sapiens";
private string Name { get; set; }
}
Static means belonging to a class, intrinsically. For instance, the SpeciesName of Human is "Homo sapiens". This contrasts with the non-static (or instance) property Name. A human, an instance of the Human class, can have a name. An instance of class Human with name Bob makes sense; a Human class with a static Name of Bob would be... interesting.
How to pass state between pages in C# UWP
2 recommended options: Reference
Pass data when changing from one page to another via Frame.Navigate().
Store your data statically for global access.
Personally, I prefer the second option. I usually have an object called Model that holds all of my application's persistent state. I store my only instance of Model as a static property of the App class.
For example, let's say on page1 the user must choose red or blue. Page2 will be that color. So the code would be something like:
class App : Application {
public static Model GlobalModel { get; set; }
//...
}
class Model {
public Color UserSelectedColor { get; set; }
}
class Page1 {
//...
private void StoreSelectedColor(Color selectedColor) {
App.GlobalModel.UserSelectedColor = selectedColor;
}
//...
}
class Page2 {
//...
private Color GetSelectedColor() {
return App.GlobalModel.UserSelectedColor;
}
//...
}

Related

Xamarin.Forms Dependency Service non-static fields/properties

I'm using Dependency Service to get the platform specific implementation of an interface.
Let's say I have the following interface:
public interface IMyInterface
{
bool IsEnabled { get; set; }
}
And the implementing class in my Android project:
[assembly: Dependency(typeof(MyClass))]
namespace App.Droid
{
class MyClass : IMyInterface
{
public bool IsEnabled { get; set; }
}
}
At some point in the code, I set IsEnabled to true.
After that, I start a new activity that makes my app go to background:
Intent intent = new Intent();
intent.SetAction(action);
intent.SetFlags(ActivityFlags.NewTask);
MainActivity.Instance.StartActivity(intent);
When my app returns to foreground, I access the property IsEnabled and I get false instead of true. This actually happens with every single property and private field of the impementing class. Are those properties garbage collected when I leave the app for a new activity?
The only way I found to solve this issue is to make all backing fields static, but this makes a lot of overhead in the code, which might be unnecessary if I knew the reasons under this behavoiur.
Not too understanding the title of your question.
If you use the singleton pattern, you can extract the properties based on the unique instantiation object when needed.Like this:
public class Singleton
{
// Define a static variable to hold an instance of the class
private static Singleton uniqueInstance;
// Define a private constructor so that the outside world cannot create instances of the class
private Singleton()
{
}
/// <summary>
/// Define public methods to provide a global access point, and you can also define public properties to provide global access points
/// </summary>
/// <returns></returns>
public static Singleton GetInstance()
{
// Create if the instance of the class does not exist, otherwise return directly
if (uniqueInstance == null)
{
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
If not, you can use Properties (https://learn.microsoft.com/en-us/dotnet/api/xamarin.forms.application.properties?view=xamarin-forms)to access the data .Like this:
private void SaveConnectionData(JSON.Connection C)
{
App.Current.Properties[Cryptography.Encryption("AccessToken")] = Cryptography.Encryption(C.Access_token);
App.Current.Properties[Cryptography.Encryption("ExpiresIn")] = Cryptography.Encryption(C.Expires_in.ToString());
App.Current.Properties[Cryptography.Encryption("TokenType")] = Cryptography.Encryption(C.Token_type);
App.Current.Properties[Cryptography.Encryption("Scope")] = Cryptography.Encryption(JsonConvert.SerializeObject(C.Scope));
App.Current.Properties[Cryptography.Encryption("RefreshToken")] = Cryptography.Encryption(C.Refresh_token);
App.Current.SavePropertiesAsync();
}
You may be involved in the use of lifecycles and notifications.Also if there is a lot of data, consider using the SQLite database to save this data .Can refer to this link here
More:In Xamarin.Android, you also can try lifecycles to show saved data.Like OnResume method to show data.

How to return class instance from static class?

I want use a static class that must contains global variables, so I can access to all application controls simply from a variable.
Actually I've this implementation:
public static class Globals
{
public static HeadToHead Head2Head
{
get { return Resources.Controls.HeadToHead; }
}
}
in the case above, I want return the instance of HeadToHead control, the control look like this:
public partial class HeadToHead : UserControl
{
public static int HomeId = 0;
}
my goal is to access to the static variables of this control, like: Globals.Head2Head.HomeId
but I get this error on this line: get { return Resources.Controls.HeadToHead; }
HeadToHead is a type which is not valid in the given context
You're returning what looks like a type from a property that seems to be declaring an instance of that type. If you truly want to return that type, there's syntax for that (I don't remember any more, I think in c# it's classname.type). If you want to return an instance, then you need to get that instance from somewhere.
As an aside, static instances of UI controls are a bad idea, and a code smell.
You have to instantiate an instance of the type and return that. As you want a single global instance you could use the static constructor.
public static class Globals {
static Globals(){
Head2Head = new Resources.Controls.HeadToHead();
}
public static HeadToHead Head2Head { get; private set; }
}
There are few situations in which you would actually want to do this but common static settings that do not change in the life of the application might be one of them. As HeadToHead inherits from UserControl that does not really seem to be the case, an instance of a UserControl should ideally never be static.

Current User Global Variable C# Desktop app

I know that you can use session variables in web apps, I can't figure out how to use one in a desktop (windows forms and not a mobile android) one.
I have a Player class that is used to associate players with other classes in the app/SQLDb (they may or may not be the active user). But I want to have a CurrentPlayer (the person who actually has the application running) set.
In the Program class at start up, I'm running checks to see if the current user exists and if not, add them to the SQLdb. But at that time I'd like to set up an application-wide object for the user I've just added. In fact, if they're not in the db they can't run the app.
Obviously static doesn't work because I don't want to make the Player class static all the time. But I really do need to have this object set and the info easily available. EDIT: The reason it can't be static all the time is that in every other instance but the current user, I definitely want the creation of a player object to take place. I guess it's like the old Marine Corps thing. There are many players but this one is mine.
Yes, I know, global variables are not generally good, but here it makes sense (well I think so, if you all have other ideas I'm all ears), I just can't figure out how to implement it.
EDIT: I may not be being clear here. I guess I kind of need a singleton maybe? but I don't know in which file to declare the instance or how.
I have a MYAPPPlayer class that is used generally for many many instances, it can/should not be static (unless I want to be a crappy dev). But I need a MYAPPPlayer global singleton object variable for the current user of a non-web, desktop csharp app.
In your application you should have a static User CurrentUser property.
When you log into the application, set the Current User to the instance of that user.
If you are using WPF, I would make this a dependency property and have the rest of your application's interface bind to that property. If you are using forms, you'll have to manually handle the updating of all the UI when the user changes.
Edit: Short example of how something like this could be implemented with a static running program and a static INSTANCE of an object. I would also recommend you read more about what static means, and what a class is, it might be a bit more than you think... I'll explain a bit more at the bottom
class Program
{
static Player CurrentUser;
static void Main(string[] args)
{
string username;
bool isValidUser;
//get and validate user credentials
if (isValidUser)
CurrentUser = new Player(username);
SomeMethod();
}
static void SomeMethod()
{
if (CurrentUser == null)
return;
//do stuff with user
}
}
public class Player
{
public string Name { get; private set; }
//... more properties
public Player(string name)
{
Name = name;
//... more properties
}
}
Think about static vs non-static as such..... Non static classes are the blueprints for objects that you can construct and have multiple instances of. A static class is created when you have static members in a class. All the static members are separated out and a single instance of this static class is declared and referenced throughout your entire program whenever you reference one of those static members.... a better example of what I am saying is....
class Program
{
static Person John;
static void Main()
{
Console.WriteLine("Persons who exist {0}", Person.Total);
John = new Person("John");
John.Born();
John.Birthday();
Person Jane = new Person("Jane");
Jane.Born();
Console.WriteLine("Persons who exist {0}", Person.Total);
Console.WriteLine("John's Age {0}", John.Age);
Console.WriteLine("Jane's Age {0}", Jane.Age);
Console.ReadKey(true); //Pause program
}
}
class Person
{
public static int Total { get; private set; }
public static Person()
{
Total = 0;
}
public string Name {get; private set;}
public int Age { get; private set; }
public Person(string name)
{
Name = name;
Age = 0;
}
public void Born()
{
Total++;
}
public void Birthday()
{
Age++;
}
public void Death()
{
Total--;
}
}
As you can see above I have a static main method who has access to a John Person. The Person Class is non-static, however it does have a static member. Notice that the instances of Person internally can access the static variables, but from the main method you must say Person.Total to get the total. Also note that the static part of the Person class has no access to any of the instances of Person, but all instances of Person have access to the static members of Person, this is how they can iterate up the total amount of Persons when one is born, or iterate down when one dies.
The CurrentPlayer could be static since it's the current player.
internal class Data
{
public Player CurrentPlayer { get; set; }
.... // other variables
}
Usage: Data.CurrentPlayer = ResponseFromWebServiceCall.Player;
There's nothing wrong with having a static variable to represent the current player if there can be only one current player at a time.
Edit, to clarify: If there is only to be a SINGLE representation of an object, then using a static variable to hold that information is perfectly acceptable. In your classes, it's up to you if you want to reference that player variable as I have shown above with usage, or if you want to accept the player variable through a constructor parameter, for example. Actually, doing it that way would give you the best trade-off for portability.

Why objects are orphan, when creator exist

Consider following code
public class City
{
public string Name { get { return "New York"; } }
Building empEstate;
Building nyTimes;
public void Init()
{
// I hate passing "this" to all object
empEstate = new EmpEstate(this);
setSomeProperty(empEstate);
// any one can create new object of some other city
// and pass to the building
nyTimes = new NYTimes(this);
...
other = new OtherBuildings(this)
}
public void PrintAddresses()
{
empEstate.Print();
nyTimes.Print();
...
other.Print();
}
}
public abstract class Building {
City _city;
public Building(City city){
this._city = city;
}
public abstract string Name { get;}
public void Print(){
Console.WriteLine(this.Name);
Console.Write(",");
Console.WriteLine(this._city.Name);
}
}
First thing I want better solution to this approach. Print is just an example. Actually each building object raise some event to City object. I don't want to add handler to each building as there could be several buildings in city. Also I do not want to add each of them into list, as it is two task for each building (one initialization and second add to list, one forget to add to list when writing new building). For this, I want caller to be automatically available to callee, like Parent property of control (though it was added to this.Controls)
Using memory, can we know who is the parent of current object. How does GC knows that object is not being referenced (including creator). Can't we create a method (safe or unsafe) using memory to identify the caller object. I see we can use StackTrace to see the call hirarchy, can we intercept here when a new object is being created.
Building factory on city solved my problem of passing this to each object
public interface ICity
{
string Name { get; }
}
public abstract class City : ICity
{
public T CreateBuilding<T>()
{
T buildingInstance = Activator.CreateInstance<T>();
((IBuilding)buildingInstance).SetCity(this);
return buildingInstance;
}
public abstract string Name { get; }
}
interface IBuilding
{
ICity City { get; }
void SetCity(ICity city);
}
public abstract class Building : IBuilding
{
private ICity _city;
public ICity City { get { return _city; } }
public void IBuilding.SetCity(ICity city)
{
this._city = city;
}
public abstract string Name { get; }
public void Print()
{
Console.WriteLine(this.Name);
Console.Write(",");
Console.WriteLine(this._city.Name);
}
}
public class EmpEstate : Building
{
public override string Name { get { return "Emp State"; } }
}
public class NYTimes : Building
{
public override string Name { get { return "NY Times"; } }
}
public class NewYorkCity : City
{
public override string Name { get { return "New York"; } }
EmpEstate empEstate;
NYTimes nyTimes;
public void Init()
{
// Now I dont need to pass this
empEstate = this.CreateBuilding<EmpEstate>();
setSomeProperty(empEstate);
// now any one cannot create building in new your and
// say it belongs to Philedelphia :)
nyTimes = this.CreateBuilding<NYTimes>();
}
public void PrintAddresses()
{
empEstate.Print();
nyTimes.Print();
}
}
Problem was there were several classes already created and for new functionality we needed the creator object in the base class of Building Object. We did not wanted to modify the constructor of each class and pass this object to each. And City class (in example) was basically code on plugin side, so allowing them to pass city (if plugin developer pass wrong city) may disturb the functionality of entire app. So modifying the plugin base solved my purpose. Suggestions are welcome.
There is no logical "owner" of an object. Inspecting the stack trace is... not usually ideal. By comparison to Parent, that is not very different to your existing approach - merely that is set via methods/properties rather than in the constructor.
If the city is only necessary for the context of methods like Print, why not pass it in as a parameter, i.e. nyTimes.Print(this) etc. If you might need other values, rather than taking lots of parameters, consider using some kind of context object that has a city - i.e.
class PrintContext {
public City City {get;private set;}
// other stuff...
public PrintContext(City city/*, other stuff...*/) {
City = city;
}
}
I think you are misusing the terms parent and creator. The object that created the instance has no special relationship with the instance (e.g. factories create objects, but do not maintain references to them), so, in general, there is no way to find out who or what created a concrete instance.
In the same sense, parent has no meaning on a general object. We can somehow infer that the Form is parent to the TextBox, but that is not a special relationship. It this case it just means that the TextBox is in the form's Contols collection, and that it's Parent is set to the Form.
You are right that this could potentially lead to inconsistencies (Form1 thinks that TextBox is it's child, but the TextBox thinks that it's Parent is Form2), but I do not know of, and don't think there is a better solution of this kind of relationship than the Children collection / Parent reference.
Picking a few of your many questions:
I hate passing this
Why? You are telling the building which city it belongs to. How else could you do this. I see that as a common idiom for wiring objects together.
Also I do not want to add each of them into list, as it is two task
for each building (one initialization and second add to list, one
forget to add to list when writing new building).
I'm not clear what list you want to add them to, but your concern about "forgetting" is overcome if you do the work in the base constructor:
public Building(City city){
this._city = city;
// add the building to the list here - nothing to "forget"
}
As for GC, once a creator has created something there is no relationship between them unless you choose to retain a reference. You have done that with
empEstate = new EmpEstate(this);
so as long as the City is not a candidate for garbage collectio then the EmpState won't be either.

MonoState, Singleton, or Derived Forms: Best approach for CRUD app?

I have a fairly large CRUD WinForm app that has numerous objects. Person, Enrollment, Plan, CaseNote etc. There are over 30 forms that make up the app with the UI broken down logically. Member, Enrollments, Plans, CaseNotes, etc.
I am trying to figure out how I can create my Person Object after searching on the Search Form and pass THE object to the next requested form. Whatever that may be, let's say Demographics. The short of it is that I need the Person object to be available throughout the App and there can only be one.
Now I have ZERO exposure to Design Patterns but I am trying. I have read http://www.switchonthecode.com/tutorials/csharp-tutorial-singleton-pattern and http://www.yoda.arachsys.com/csharp/singleton.html but I want to make sure I understand correctly how to apply this to my situation.
First, the examples state that you are accessing a reference, correct? Am I mistaken or would I need to access the value?
Second, is there anything else that I need to do to make this Globally available? Do I just declare a instance on each form but through this Singleton Pattern so as to not have more then one?
Thanks
EDIT 1
To clarify, All objects are child objects of Person. Also, As the Search Page eludes to; the users can select a different currentPerson. But they can only interact with ONE Person at a time.
Lastly, as I stated I am an infant in this and if I should be considering something else, a different approach please say so and if you'd be so kind as to offer some explanation as to why, I'd be very grateful.
EDIT 2
Based on Medicine Man's comment I thought I wauld clarify.
First, Thank you to everyone who has contributed so far.
Second, I don't know the first thing about design patterns and I certainly don't have the foggiest if a certain one is needed in my current situation.
If someone has a better, simpler, or ,in your opinion, a more fitting method of passing a Data Object from FORM to FORM to FORM then PLEASE tell.
In the end I just need a way of tracking the information as my users go from place to place.
Thank You
First, the examples state that you are accessing a reference, correct? Am I mistaken or would I need to access the value?
Your class that you are accessing is a reference to a single class in memory. For example, say your class is:
public class Person { ... }
If you have a singleton of that, you'll have a single "Person" saved in memory, with a shared reference to that one person in the singleton. When you access your single person, you'll be working with that reference, which is probably what you want. Any changes to the person will change it everywhere.
Second, is there anything else that I need to do to make this Globally available? Do I just declare a instance on each form but through this Singleton Pattern so as to not have more then one?
Singletons are used to basically enforce that every time you use the object, it's the same object (each use is a separate reference to the one, single object in memory). You can just grab the singleton anywhere you need it, and it'll just work.
You can use the Singleton pattern to assure that only one instance is ever created.
However, the jury is still out (at least in my mind) on whether this is a good decision. There's plenty of reading on SO and other places about this.
I would approach this from a different angle. I'd make all of my forms take in a Person instance in the constructor. That way, each form is only ever worried about it's instance of Person.
You could do this by creating a new class that inherits from Form and has a field/property/constructor for your Person. Then, any form that uses Person can inherit from your new class.
You would, of course, have to manage the creation of your Person object. You could even do this with a singleton. However, the benefit is that each form doesn't have to know how to create a Person or who created the Person. That way, if you choose to move away from the Singleton pattern, you wouldn't have to go change all of your references to your singleton instance.
EDIT:
Here's some code to demonstrate this. It took me a while to get the designer to play nice. I had to add an empty private constructor in PersonForm to get the designer to not throw an error.
Program.cs
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MyDerivedForm(new Person { Name = "Hello World!" }));
}
}
Person.cs
public class Person
{
public virtual string Name { get; set; }
}
PersonForm.cs
using System;
using System.Windows.Forms;
public class PersonForm : Form
{
private readonly Person myPerson;
protected virtual Person MyPerson
{
get
{
return this.myPerson;
}
}
private PersonForm()
{
}
public PersonForm(Person person)
{
this.myPerson = person;
}
}
MyDerivedForm.cs (add a label named label1)
public partial class MyDerivedForm : SingletonMadness.PersonForm
{
public MyDerivedForm(Person person)
: base(person)
{
InitializeComponent();
}
private void MyDerivedForm_Load(object sender, EventArgs e)
{
label1.Text = this.MyPerson.Name;
}
}
You could do something like this:
public static class PersonController
{
private static Person _Person;
public static Person GetPerson()
{
if (_Person == null)
_Person = new Person();
return _Person;
}
}
This will ensure there is only one person object. You will be getting a reference to the _Person object, not a copy, so any changes will be to the single object you're expecting.
As Reed says, singletons enforce that the same object is used throughout the application. However, from your question it doesn't look to me like you do have the same instance of the person class available throughout the entire application, since there is the "search form" which looks like it allows you to change the currently selected person.
In this case your singleton may need to be a container class that holds the current context of the application and which person is currently selected. This may be something like:
public class Context
{
private static Context _instance;
public static Context Instance
{
get
{
if (_instance == null)
{
_instance = new Context();
}
return _instance;
}
}
public Person CurrentlySelectedPerson { get; set; }
private Context() { }
}
(Note that this isn't an ideal singleton pattern since it isn't thread safe...)
Then the search form would set the currently selected person with:
Context.Instance.CurrentlySelectedPerson = personSelectedInForm;
And the demographic from can use it like:
//Get the demographics for the current person
ShowDemographics(Context.Instance.CurrentlySelectedPerson);
You could also use the monostate pattern with your Personclass.
public class Person
{
public Guid Id { get; set; }
public String FirstName { get; set; }
public String LastName { get; set; }
}
Build a monostate object for Person.
public class CurrentPerson
{
public static Person Person { get; set; }
public Guid Id
{
get { return CurrentPerson.Person.Id; }
set { CurrentPerson.Person.Id = value; }
}
public String FirstName
{
get { return CurrentPerson.Person.FirstName; }
set { CurrentPerson.Person.FirstName = value; }
}
public String LastName
{
get { return CurrentPerson.Person.LastName; }
set { CurrentPerson.Person.LastName = value; }
}
}
Now you can initialize the monostate.
CurrentPerson.Person = GetPersonByUserInput();
And then use CurrentPerson instances throughout the code and they will all access a common shared state.
CurrentPerson currentPerson = new CurrentPerson();

Categories