access a Form1 public function from static class inside Form1 - c#

When writing this post i was checking all questions asked with related subject
and couldent find a simple answer to this Newbs C# issue
i would like ... if i may , to have as much as it can be a well-explaind answer (Please!)
i made a public static class
public static class MyLoadedBtmpToolBox
{
public static string FnameToLoad;
public static bool PutLoadedByteArrInPicbox;
public static string[] LoadedRefrnce;
public static int SourceX_Loaded, SourceY_Loaded, RectWidth_Loaded, RectHeight_Loaded;
---> public static int tst = Str2Int(LoadedRef[0]);
public static byte[] LoadedByteArr;
}
this calss as usually does by default, is within the main form i am using
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;
using System.Diagnostics;
using System.Drawing.Imaging;
using System.IO;
using System.Security.Cryptography;
using WindowsInput;
namespace MyScrCupTry1
{
public partial class MyForm1 : Form
{
public static class MyLoadedBtmpToolBox
{
public static int testStr2Int = Str2Int("100");
}
public int Str2Int(string STR)
{
int strInt = Convert.ToInt32(null);
if (isntEmpty(STR))
{
strInt = Convert.ToInt32(STR);
}
else
{
MessageBox.Show("theString " + STR + " is Null");
}
return strInt;
}
}
i can't assing the testStr2Int a value , by using my public "helper Method" Str2Int() from the main form
i am Getting Error :
Error 1 An object reference is required for the non-static field, method, or property 'MyScrCupTry1.MyForm1.Str2Int(string)' G:\RobDevI5-Raid-0\Documents\Visual Studio 2010\Projects\WindowsFormsApplication2\WindowsFormsApplication2\MyForm1.cs 95 45 MyScrCuptry1
What is the right way for accessing Main Form Public elemets from a static Class
if it is possible / (not illegal)...
ReEditing
after Those two answers ...
I tried to implement
the code from first answer without expected results i guess i didn't know the right code structure with override OnLoad(..) thing ...
BUT !
i have turnd the method Str2Int(STR) from public into public static
so now elements from the form itself still have access (i am surprised) to Str2Int()
and from the static Class I Can Access it too....
and its all thanks tp making it into static too ,
am i missing somthing else is there "hidden" drawback when changing Str2Int() from public into public static ?

The point of static code is that belongs to itself, rather than any other object. For this to be true, when you set something as static, everything that depends on it must also be static!
This is what your error message is trying to tell you. You are declaring something as static, but in the computation of that static, you are using something that is not static. Str2Int is not tagged as static, so that is an immediate problem, and it's possible that LoadedRef is also not static. I am half-sure you actually meant to use LoadedRefrnce there, in which case you're fine, but since you spelled nothing correctly I can't be sure!
Check this page for an explanation of the static keyword, also please make more of an effort to read up on C# coding conventions - this makes it much easier for people to read your code when you ask for help like this!
Expanding upon the edits above:
The 'drawback' to making code static is that it pretty much instantly makes everything it is a part of untestable. The idea behind unit testing is to have all of your code broken out into totally replaceable parts, so they can be tested separately and moved out separately (if need be). By making a bunch of code static, you are essentially welding it to any other code it might be a part of. In your own example, by making Str2Int() public static, everything that uses Str2Int() is now untestable!
Static code is, generally speaking, a vice that you should attempt to avoid as much as possible. There are places where you can't, and if you are just starting to learn really the biggest focus is just getting something working. But be ready to look back on this code and go cold at how you could've ever written something so bad in a few years, when you are more experienced and confident in your skills.

add Form object to static class, like this :
public static class MyLoadedBtmpToolBox
{
public static Form MainForm {get;set;}
public static int testStr2Int = MainForm.Str2Int("100");
}
and from the Form :
public partial class MyForm1 : Form
{
private override OnLoad(..){
base.OnLoad(...);
MyLoadedBtmpToolBox.MainForm =this;
}
}
This design is fragile by itself, as you has to gurantee that MyForm property is intialized before it's used to call ..testStr2Int = MainForm.Str2Int("100")...
So, considering that testStr2Int is public, may be intialization of it you can do in Form too and not in static class.

Related

A namespace cannot directly contain members such as fields, methods or statements in .Net 6 [duplicate]

My understanding is that it is similar to write code directly into the old "static void Main(string[] args)" without the need to display what's above.
However, I used to declare my variables in the class Program to have them accessible from other classes (apologies if not best practice, I learnt C# by myself and as long as it works, I'm happy with my code).
See example below:
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.IO;
namespace myNameSpace
{
class Program
{
//variables declaration
public static string abc = "abc";
public static int xyz = 1;
static void Main(string[] args)
{
//code goes here
}
}
}
With C# 9, it seems I can only declare variables in the Main section, so how can I declare them to be able to access them from other classes?
I don't think the currently-accepted answer is correct, if you toss a partial class signature in Program.cs you can most certainly add things like static-scoped fields and attributes:
var customAttributes = (CustomAttribute[])typeof(Program).GetCustomAttributes(typeof(CustomAttribute), true);
Console.WriteLine(customAttributes[0].SomePropery);
Console.WriteLine(MyField);
[Custom(SomePropery = "hello world")]
public partial class Program
{
private const string MyField = "value";
}
class CustomAttribute : Attribute
{
public string SomePropery { get; set; }
}
The above code and nothing else in Program.cs will output:
/home/dongus/bazinga/bin/Debug/net6.0/bazinga
hello world
value
Process finished with exit code 0.
I use this method to apply the [ExcludeFromCodeCoverage] attribute to my projects' Program.cs files
For .Net 5:
When you use the Top-Level Program feature of C# 9, you give up the ability to put anything outside the Main method scope. Fields, properties, attributes on the Main method or Program class, setting the namespace, changing the class name, etc are all no longer available (the only exception is "importing" namespaces with using lines).
If that limitation doesn't work for you, don't use the feature.
For .Net 6 and higher, use dongus's answer.

How do I add code outside the scope of Main when using C# 9 Top Level Statements?

My understanding is that it is similar to write code directly into the old "static void Main(string[] args)" without the need to display what's above.
However, I used to declare my variables in the class Program to have them accessible from other classes (apologies if not best practice, I learnt C# by myself and as long as it works, I'm happy with my code).
See example below:
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.IO;
namespace myNameSpace
{
class Program
{
//variables declaration
public static string abc = "abc";
public static int xyz = 1;
static void Main(string[] args)
{
//code goes here
}
}
}
With C# 9, it seems I can only declare variables in the Main section, so how can I declare them to be able to access them from other classes?
I don't think the currently-accepted answer is correct, if you toss a partial class signature in Program.cs you can most certainly add things like static-scoped fields and attributes:
var customAttributes = (CustomAttribute[])typeof(Program).GetCustomAttributes(typeof(CustomAttribute), true);
Console.WriteLine(customAttributes[0].SomePropery);
Console.WriteLine(MyField);
[Custom(SomePropery = "hello world")]
public partial class Program
{
private const string MyField = "value";
}
class CustomAttribute : Attribute
{
public string SomePropery { get; set; }
}
The above code and nothing else in Program.cs will output:
/home/dongus/bazinga/bin/Debug/net6.0/bazinga
hello world
value
Process finished with exit code 0.
I use this method to apply the [ExcludeFromCodeCoverage] attribute to my projects' Program.cs files
For .Net 5:
When you use the Top-Level Program feature of C# 9, you give up the ability to put anything outside the Main method scope. Fields, properties, attributes on the Main method or Program class, setting the namespace, changing the class name, etc are all no longer available (the only exception is "importing" namespaces with using lines).
If that limitation doesn't work for you, don't use the feature.
For .Net 6 and higher, use dongus's answer.

C# use static class properties as if they were namespaced?

I am trying to create a class to hold all my global constants, e.g.:
namespace MyProj
{
public static class Constants
{
public const string MY_STRING = "this needs to be used ad nauseum";
}
}
This works great. However, the result is that in code I have to always type:
doSomethingWith(Constants.MY_STRING);
When what I really want to be able to do is go (something like):
using MyProj.Constants;
doSomethingWith(MY_STRING);
How can I achieve this?
Add static to your using:
using static MyProj.Constants;
Details here.

Is it possible to write a extension method for an abstract class

Why I'm unable to extend an abstract class. Is there any work around to achieve this?
In silverlight, Enum.GetNames is missing. So, I would like to extend it and have it in my utility assembly. By then, got into this.
The problem here is not that you can't add an extension method to an abstract class (you can - you can add an extension method to any type) - it's that you can't add a static method to a type with extension methods.
Extension methods are static methods that present themselves in C# as instance methods. But they're still static. Adding a static method to a type requires the ability to redefine the type, which you can only do if you have the source code :)
Best bet, if you want this method, is to write your own static and see if you can perhaps rip the code out of reflector.
However, it's entirely possible that it's not there because it's physically not supported in Silverlight (I don't know - I haven't investigate)
EDIT
Following on from your comment - and I hope that I've understood you here - I think what you want to be able to do is something like this (targetting object to prove the point):
public static class ExtraObjectStatics
{
public static void NewStaticMethod()
{
}
}
public class Test
{
public void foo()
{
//You can't do this - the static method doesn't reside in the type 'object'
object.NewStaticMethod();
//You can, of course, do this
ExtraObjectStatics.NewStaticMethod();
}
}
If you think about it - of course you can't inject new static methods into an existing type because, like I said in paragraph two, you have to be able to recompile the underlying type; and there simply is no way around that.
What you can do is (and I don't actually recommend this - but it's an option) create yourself a new type called Enum and place it inside a new namespace:
namespace MySystem
{
public class Enum
{
public static string[] GetNames()
{
//don't actually know how you're going to implement it :)
}
}
}
And now - when you want to use it, what you can't do is this:
using System;
using MySystem;
namespace MyCode
{
public class TestClass
{
public static void Test()
{
Enum.GetNames(); //error: ambiguous between System and MySystem
}
}
}
Because the using in the outermost scope to both 'System' and 'MySystem' will cause the compiler not to be able to resolve the correct Enum type.
What you can do, however, is this:
using System;
namespace MyCode
{
using MySystem; //move using to inside the namespace
public class TestClass
{
public static void Test()
{
//will now work, and will target the 'MySystem.Enum.GetNames()'
//method.
Enum.GetNames();
}
}
}
Now, code within that namespace (within that file only) will always resolve Enum to the one in your namespace because that's the nearest using directive in terms of scope.
So, you can think of this as overriding the whole Enum type for the benefit of a given namespace that includes a using MySystem; in it.
But, it does exactly that - it replaces the existing System.Enum with MySystem.Enum - meaning that you lose all the members of the System.Enum type.
You could get around this by writing wrapper methods in your Enum type around the System.Enum versions - making sure that you fully-qualify the type as System.Enum.
Having looked at the implementation of the GetNames method in Reflector - it relies on internal data that I don't think you're going to be able to build... but I would be very interested to hear if you are actually able to reproduce the method in Silverlight.
public abstract class Foo
{
public abstract void Bar();
}
public static class FooExtensions
{
// most useless extension method evar
public static void CallBar(this Foo me)
{
me.Bar();
}
}
Sure, no problem.

C# and Variable Scope in Winforms

Within a Winform app, I would like data in an instantiated class to be accessible by multiple form controls.
For example, if I create Class Foo, which has a string property of name, I'd like to instantiate Foo a = new a() by clicking Button1, and when I click Button2, I'd like to be able to MessageBox.Show(a.name). There may be multiple instances of Foo, if that matters at all.
What is my best option for being able to use class instances in such a way?
A private field or property of a class satisfies the requirement - such field can be accessed by all methods of the class.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace Test
{
public partial class Form1 : Form
{
foo a;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
a = new foo();
a.name = "bar";
}
private void button2_Click(object sender, EventArgs e)
{
if (a != null && a.name != null)
MessageBox.Show(a.name);
else
MessageBox.Show("");
}
}
public class foo
{
public string name { get; set; }
public foo() { }
}
}
If you want this variable to be accessible to other forms you'd need to make it public (preferably as property) - C# winform: Accessing public properties from other forms & difference between static and public properties
maybe you just want a static class
Winforms are nothing but some graphical elements backed by code. The code can own/create objects just like regular 'non-winform' code. The same scoping rules apply.
My guess if yours is more a problem of 'how does my form access shared state defined outside of it'? Create a static class, or have a setter on the class of your form that other code can use to set this shared state.
A form you create is just another class, derived from Form. A class exists in a given namespace, so you just need to create your Foo class in a namespace shared by your application's forms.
If a class is shared by multiple forms, then usually you'd separate out that class into a separate file.
Jon Skeet [C# MVP]
Guest Posts: n/a
2: May 15 '07
re: Application variables in csharp.
On May 15, 12:04 pm, Control Freq
wrote:
Quote:
Still new to csharp. I am coming from a C++ background.
>
In C++ I would create a few top level variables in the application
class. These are effectively global variables which can be accessed
throughout the application because the application object is known.
>
What is the csharp equivalent of this practice?
I can't seem to add variables to the "public class Program" class and
get access to them from other files.
>
I am probably missing something obvious.
Basically you want public static fields (or preferably properties).
An alternative to this is a singleton:
http://pobox.com/~skeet/csharp/singleton.html
Jon
When in doubt, find something signed by John Skeet. Found on: http://bytes.com/topic/c-sharp/answers/646865-application-variables-csharp

Categories