How to call method from different class in MainWindow - c#

I want to call a method from 'Check.cs' in MainWindow.
I've tried to set instance.
Check ch = new Check();
class Check
{
public static string IsOpen(string text)
{
// My logic
}
}
I expected to be able to set instance, but whenever I want to I can't find it, also I'm not able to set it.

First of all, make your class public. Now you should get errors trying to create instance of that class.
Then, you need to add reference to library (.dll) that this is compiled to, unless this is in the same project.
Also, you need using directive to point to a namespace, where Check class is located.
Finally, as already said, your method is static, so you don't need to create instance to call this method. Although it can be called on an instance as well. So both ways are valid:
var ch = new Check();
ch.IsOpen();
Check.IsOpen();

Related

Using the "this" keyword in a different class c#

I made a program that works just fine as-is, however i want to organize code better by moving some of my logic into other .cs files; upon moving some code i noticed that code reffering the "this" keyword for changing the applications width / height no longer function and ive had no luck trying to get a handle to "this", please help
int heightd = (int)this.Height;
Edit: To further clarify. My mainwindow.xaml.cs is where all my code was before.
I would use this.width to get my windows width.
Upon creating a different .cs file to hold related methods, it broke all of my "this" refferences.
I want for my NEW cs file to be able to get a handle on "this" from my main program. so i can call its width, height, etc
Re-edit: I understand that "this" is not going to function properly from my new class I just want to be able to create methods that use the same object that is accessed when "this" is refferenced.
So for example, Class2 can do WorkAround.height ; where WorkAround is a handle to whatever "this" is in class 1.
Soution: updated signature in new class to accept the main window:
public static void Marginnn(MainWindow aplication)
{
send "this" from main class during the call:
WindowsInterop.Marginnn(this);
Others have discussed partial classes, which can be problematic. For this answer, I assume by "move to another .cs file" you mean "move to another class," as your title indicates.
The this keyword is effectively a variable that refers to the instance that "owns" the current method. If the method is moved to another type, then the instance can no longer be the owner of the method. Instead, you need to pass a reference to the instance into the method instead. That will be a method parameter, which will have a name other than this.
Example; before:
class App
{
public void DoSomethingWithTheHeight()
{
int heightd = (int)this.Height;
//more code
}
public void CallDoSomethingWithTheHeight()
{
this.DoSomethingWithTheHeight();
}
}
Task: move DoSomethingWithTheHeight to a new static class:
class App
{
public void CallDoSomethingWithTheHeight()
{
NewClass.DoSomethingWithTheHeight(this);
}
}
static class NewClass
{
public static void DoSomethingWithTheHeight(App application)
{
int heightd = (int)application.Height;
//more code
}
}
Task: move DoSomethingWithTheHeight to a new non-static class:
class App
{
public void CallDoSomethingWithTheHeight()
{
NewClass instanceOfNewClass = new NewClass();
instanceOfNewClass.DoSomethingWithTheHeight(this);
}
}
class NewClass
{
public void DoSomethingWithTheHeight(App application)
{
int heightd = (int)application.Height;
//more code
}
}
There are other possibilities, but these examples should illustrate the basic principle.
If you only want to move part of your class to another file and still use this, you have to use a partial class. But I won't recommend this approach, your code clearly needs some refactoring.
C# keyword this refers to the current instance of the class it's being used in. It can be used for a few other things such as a modifier of the first parameter of an extension method, but we won't worry about that here. So, you may only use this from within the class that it's referring to and note that it may not be used with static classes, methods, fields, etc... since they have no instance associated with them.
If the code you're referring to is not implemented within a partial class, then it has to refer to the instance of the Window. Otherwise, it's impossible to tell what this is. Since we don't know how exactly you're structuring your program, it's hard to recommend a method of fetching the instance of the Window in question. If, for example, you would use the MVVM pattern, you wouldn't even need to interact with the instance of the UI from within the code. However, if you're working with a code-behind model, then your best bet is probably to create a partial class for that window. Like I said, it's hard to know what's right in your situation without knowing the entire scope of your environment.
There are lots of ways to tackle this and some are more hackish than others:
// In the code-behind of a window...
public static MyWindow Instance { get; private set; }
public MyWindow()
{
Initialize();
Instance = this;
}
// Somewhere else in your program...
var someValue = MyWindow.Instance.SomeControl.Value;
Note that the above code is just for demonstration purposes and not something I would recommend doing (it doesn't even account for null, but that's easy to fix). It's simply a demonstration showing that there are almost countless ways of tackling your problem. Ideally, if you're not going with MVVM, I would probably implement a window manager class that handles instances of all of your application windows.

Initialize static class implicitly

is it possible to initialize a static class on app start up "automatically"?
By automatically I mean without the need of referencing a property.
The reason I want to be able to do this for is that I'd like to automatically theme an app on start up.
Here's a short snippet:
static class Settings{
private static Theme _defaultTheme;
public static Theme DefaultTheme{
get{
return _defaultTheme;
}
private set{
_defaultTheme = value;
ThemeManager.SetTheme(value);
}
}
static Settings(){
DefaultTheme = Themes.SomeTheme;
}
}
I know I can ( and that's how it is at the moment ) go with original getter/setter and call
ThemeManager.SetTheme( Settings.DefaultTheme );
in constructor of App ( it's WPF project ) and it'll do the job, however, at least from my point of view ( correct me if I'm mistaken please ) it'd make more sense for the default theme to apply without the need of explicitly stating it.
is it possible to initialize a static class on app start up "automatically"? By automatically I mean without the need of referencing a property.
The only way to guarantee that the static constructor will execute is to use the type in some form. It does not necessary need to be referencing a property (it could be constructing an instance, using a method, etc), but you do need to use the type. It is possible for the static constructor to never run otherwise.
Your current option, or a variation of it, seems like the best solution. You could change this to having a single call such as:
Settings.InstallDefaultTheme();
If you prefer, since the reference of Settings would force the static constructor to execute.

False section of condition resolved even when condition is true

I lately have had to change a piece of code to allow compatibility with an older version DLL. The DLLs have the same name and are not signed. The difference also is in some additional methods added to the new DLL.
One way to go about this which doesn't seem right to me is to reference the new DLL in the project, build and run. If you want to use the other DLL, you just replace it in the bin folder. You can avoid errors by just checking the existence of a method in a constructor somewhere using Reflection, and set a flag so that later on you can avoid calling the new functions if you are using the older version.
The strange thing to me is that the following piece of code doesn't work when using the old version:
int[] someVariable = (DLLIsNewFormat) ? DLL.CallNewMethod() : new int[5];
Basically what is happening is that the DLLIsNewFormat is False but for some reason I get the error:
Method not found: 'Int32[] [NameSpace].[Class].CallNewMethod()'.
I understand that the best way to go about this is to probably check if each function exists and then calling them using reflection. But I just don't know why the code is behaving this way. Is this just undefined behavior?
This is happening at the time that the method containing your snippet is JIT-compiled. In order for JIT-compilation to happen, the method needs to be available at the time the method is invoked. Since the method is not available, the JIT-compiler throws this exception when the method containing this code is called, before the method is even executed.
One way around this would be to define a new method:
int[] HideCall()
{
return DLL.CallNewMethod();
}
Then call this method instead of DLL.CallNewMethod() directly.
A better solution would be to define an interface in an assembly that is referenced by both your "conditional DLL" and the assembly you are conditionally using this DLL from. Have a default implementation of this interface available in the main assembly, and an alternate implementation in the conditionally-used DLL.
Then, at runtime, you can simply see if the DLL is available, use reflection to construct an instance of the class that implements this interface, and then substitute out a the reference to your default implementation with this one.
Example code:
// Interface, in an assembly visible to both of the other assemblies.
public interface IDLLInterface
{
int[] CallNewMethod();
}
// Implementation in the main program.
class DefaultDLLImplementation : IDLLInterface
{
public int[] CallNewMethod()
{
return new int[5];
}
}
static class DLLImplementation
{
public readonly IDLLInterface Instance;
static DLLImplementation()
{
// Pseudo-code
if (DllIsAvailable) {
Instance = ConstructInstanceFromDllUsingReflection();
} else {
Instance = new DefaultDLLImplementation();
}
}
}
Then you can use DLLImplementation.Instance.CallNewMethod() instead, and the right method will be called automatically.
Of course, I would suggest naming your interface with a more descriptive name so that it's apparent what it means.
What you want is to hide calls to non-existing methods from JIT.
To do so you need to make sure each of non-existent calls made in inside a function and call to such function is controlled by version condition:
private int[] WrappedNewMethod()
{
return DLL.CallNewMethod();
}
...SomeOtherMethod()
{
int[] someVariable = (DLLIsNewFormat) ? WrappedNewMethod(): new int[5];
}

Passing form object by reference

Hey! I've made a little boiler system that's controlled entirely by a form. The form components, however, call functions in a class for the boiler, radiators and so on.
I've got a little main class to that instantiates all of the classes but I'm struggling to figure out how to pass the form object to those classes so that they can access the form's components.
I guess I should be using mutator methods in each class to store the form object? How would I do this that's syntactically correct?
Thank you! ;o)
Just pass the form to each class. Store it in a private variable so the class can use it later. It is passed by reference by default.
class Boiler {
private Form parentForm;
public Boiler(Form f) {
parentForm = f;
}
}
When you pass a reference type to a method, C# (by default) will pass a copy of the reference to the method. This means that if pass the reference you have to your classes you are giving the method a copy of that reference and since both copies reference the same object both the call site and the method will have access to the same instance.
For example:
class Example
{
static void Main()
{
string s = "hello, world";
// Here we are passing a copy of the reference
// stored in "s" to "Print"
Print(s);
}
static void Print(string str)
{
// By default, "str" will be assigned the copy of the
// reference passed to this method.
Console.WriteLine(s);
}
}
I would be careful building an application in which your domain objects (in your case, Boiler, Radiator, etc.) know about the UI layer that consumes them. If you find that you need to pass a Form to one of these domain models you are probably doing something wrong. If you show us a small example of what you are trying to accomplish we might be able to help you come up with a more maintainable solution.

Calling a dynamic function into an object error

I know the title sounds a bit strange, but this has been boggling my mind for a little bit. So Intel offers this TurboBoost sidebar gadget with calls using JavaScript, and I want to write a program from scratch in C# that does the same thing. The calls stem from what I believe is an ActiveX DLL which I easily imported. The problem is, whenever I try to call a function, it gives me the error "an object reference is required for the non-static field..." I've found all of the functions e.g. the one I used return a dynamic data structure. I've tried splitting up the functions and made them both static but still no luck. Here's the code(ITurboBoostClient is the interface portion):
namespace TurboBoostMon_CLI
{
class Program
{
public static object GetCPUFreq()
{
object n = ITurboBoostClient.GetCurBaseFrequency(); //<---- error
//return Convert.ToDouble(n);
return n;
}
public static void Main(string[] args)
{
object cpubasefreq = GetCPUFreq();
Console.WriteLine(cpubasefreq); // neglect the output for now
}
}
}
If typical naming conventions are being used, ITurboBoostClient is an interface, and you do not have an instance of an object that implements the interface. Hence, the error.
Without knowing more about the ActiveX DLL, its hard to say exactly what to do, but it would be along the lines of:
{
ITurboBoostClient myClient = TurboBoostFactory.GetInstance();
object n = myClient.GetCurBaseFrequencey();
return n;
}
Note that in the first line, you call a static method that can product the class (with the interface) that is required. Then you can actually use that interface.
Look again through the ActiveX library you imported, and see if you can find a factory method, a CreateInstance method, or some other instantiator that will create the initial object.
If you're getting that error, then you need to declare something as a new object. Assuming your error marker is correct, you need to change that to create a new instance of some object that inherits the ITurboBoostClient, then use that to call the GetCurBaseFrequenct() method.
Something like:
ITurboBoostClient myTurboBoost = new TurboBoostClientObject(); // Making names up here, not familiar with the framework you're working with.
object n = myTurboBoost.GetCurBaseFrequency();
Sorry I don't know what class you need to instantiate there, but a short dig on google will most surely be revealing.

Categories

Resources