I have a grid class and a MainWindow class. Grid's class function needs to call MainWindow's function:
// function from grid class:
public Point functionFromGridClass()
{
Point variable = MainWindow.functionFromMainWindowClass(0, 0);
// ...
}
// function from MainWindow class:
public static Point functionFromMainWindowClass(int x, int y)
{
Vector2 mouse;
mouse.X = x;
mouse.Y = y + (ClientRectangle.Height - glview.Size.Height);
// ...
}
If I remove static keyword in functionFromMainWindowClass, then I can't call it from grid class. If I don't remove static keyword, then I can't use the MainWindow's class variables ClientRectangle and glview, I get a warning "An object reference is required for the non-static field, method, or property". I've never faced this problem, what should be the solution?
The grid class has to hold a reference of an instance of the MainWindow and probably provided to grid upon construction.
public class GridClass
{
private MainWindow window;
public GridClass( MainWindow Window)
{
window = Window;
}
public Point functionFromGridClass()
{
Point variable = window.functionFromMainWindowClass(0, 0);
}
}
I get a warning "An object reference is required for the non-static field, method, or property"
The warning tells you what to do: you need an instance in order to call instance methods.
So you could remove the static keyword from the method and then in your Grid class create an instance of MainWindow in order to be able to call the method:
var mainWindow = new MainWindow();
var result = mainWindow.functionFromMainWindowClass(5, 6);
It's hard to give specific advice without knowing exactly what is going on, but the general picture is that you need to somehow get the instance of the MainWindow class that you want to call the method on, either by passing it into Grid at construction or similar, or by getting it from some resource manager.
Static methods are called with reference of the className.
Call you Main window class function like this:
public Point functionFromGridClass()
{
MainWindowClass.functionFromMainWindowClass(val1, val2);
}
Related
So my problem is as follows:
I am passing an object called Items of class MyClass into a new instance of MyWindow in WPF. And I am passing by value, not by reference. Then I bind certain controls (textboxes, comboboxes, etc.) of MyWindow to the properties of a new field called ItemsReplicate of MyClass that belongs to MyWindow and is made equal to Items. However, when I make changes to any control in MyWindow, Items's properties get overwritten too for some reason. Is this normal? Or am I missing out on something?
Here's the code description:
var passThis = (MyClass)myItem;
MyWindow wnd = new MyWindow(passThis);
public partial class MyWindow : Window
{
public MyWindow (MyClass _item)
{
InitializeComponent();
innerItem = _item;
this.DataContext = innerItem ;
}
private MyClass innerItem;
}
So in the end of this procedure, any changes made via binding affects both myItem and innerItem
Many thanks.
PS: Binding mode: Two-way
Edited after comment.
Default parameter passing for classes is per reference, even without the "ref" keyword, which only makes changes to the reference of the object itself visible "on the outside".
MyClass c = new MyClass();
MyMethod(c);
MyRefMethod(ref c);
public void MyMethod(MyClass innerc)
{
innerc = new MyClass(); //stays local, c is still its old reference
}
public void MyRefMethod(ref MyClass innerc)
{
innerc = new MyClass(); //c becomes a new reference to the local innerc
}
As in your case: You pass a copy of the reference to MyClass as '_item'. You then store that reference-copy in 'innerItem' as well as in the DataContext. It is still only one Instance of MyClass with multiple reference-copies. Every copy of a reference just points to the same instance of the class.
When you modify the values of your public properties of MyClass with the binding in WPF, the values inside of your original instance of MyClass are getting an update.
In other words: This is normal behavior.
If you really want a deep copy of your Class, the easiest way is to serialize and desialize it.
My problem is, that I can't use my getter in my other class because the getter is in the MainWindow.xaml.cs class.
When I use this Code* in my other class ControlKey.cs I get an exception that the Application is hold on. I think it want's to create an other Window but I just want to use the getter in the class ControlKey.cs
MainWindow.xaml.cs Class:
public bool GetPresentationStarted(){
return presentationsarted;
}
*
ControlKey.cs Class:
MainWindow mWindow = new MainWindow();
bool presentationStarted;
And later I have an if statement where I do something if presentationStarted is true.
...
presentationStarted = mWindow.GetPresentationStarted();
...
if (presentationStarted == true) {
...
}
I don't know how to do it different. I hope someone can help me
Each instance of MainWindow has its own copy of presentationsarted. If you want the value of presentationsarted from the main window of your application, you can't just create a new instance of MainWindow. That new instance has nothing to do with the other instance that's already showing.
But you can get the actual main window itself.
var mWindow = (MainWindow)App.Current.MainWindow;
var x = mWindow.GetPresentationStarted();
That'll work, but it's not the best way to write a WPF application. You should really learn the MVVM ("Model-View-ViewModel") pattern. Then each window would have its own viewmodel that owns properties like that one, and all the viewmodels can share a reference to some common viewmodel that has state everybody cares about. WPF with the MVVM pattern is immensely powerful. The learning curve is rough, however.
Because you don't require any other parameters from the MainWindow class just try to use:
1. Static property. For example, you can create
public static bool? MainWindow.PresentationStarted {get; private set;}
and set the value from any event you prefer.
Or
2.Create shared instance like:
public static bool? SharedClass.MainPresentationStarted {get; set;}.
So you have an access to the value:
if (MainWindow.PresentationStarted == true)
To make my question as short as possible, this is my code. I wrote down the error I got in it.
public partial class VH : Form
{
public VH()
{
InitializeComponent();
//I can reach the pictureBox1 from here, but that's not what I want.
}
public static List<PictureBox> listPB;
public static bool mV()
{
bool Test = true;
listPB = new List<PictureBox>();
listPB.Add(pictureBox1); // <--- ERROR: An object reference is required for the non-static field, method, or property '...pictureBox1'
return Test;
}
I understand that I have to make the PictureBox static or available in some way but I don't know how.
I guess that picturebox1 is a control on VH that you added in the designer.
Now to your code "static" means that the function, variable or whatever else can be marked as static is not bound to an instance of your class.
So at the moment the call VH.listPB or VH.mV() from another class would be absolutly valid and because of that you get your error.
picturebox1 is not static, it needs an instace of VH but mV() could be called without an underlying instace of VH.
public bool mV()
{
bool Test = true;
listPB = new List<PictureBox>();
listPB.Add(pictureBox1);
return Test;
}
Without the static the code is valid although not very useful.
hmm I seem to have a problem, on my main window I am trying to do this:
public static readonly DependencyProperty StudentIDProperty = DependencyProperty.Register("StudentID", typeof(String), typeof(LoginWindow), new PropertyMetadata(OnStudentIDChanged));
public string StudentID
{
get { return (string)GetValue(StudentIDProperty); }
set { SetValue(StudentIDProperty, value); }
}
static void OnStudentIDChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as LoginWindow).OnStudentIDChanged(e); //
}
On my other window I have this:
MainWindow.StudentID = (String)((Button)sender).Tag;
But I get the error:
An object reference is required for the non-static field, method, or property 'WpfApplication4.MainWindow.StudentID.get'
Does anyone know how I can fix this? It works for my user controls but not other windows?
My main window is actually named MainWindow so I may have had this confused.
You need to set StudentID on an instance of your MainWindow class. Try
((MainWindow)Application.Current.MainWindow).StudentID = (String)((Button)sender).Tag;
Because MainWindow is the name of your class, not an instance of MainWindow. You need something like:
MainWindow mw = new MainWindow();
mw.StudentID = (String)((Button)sender).Tag;
I was trying to update a TextBox in the MainWindow from a UserControl and get the error
Error 1: An object reference is required for the non-static field, method, or property
'WpfApplication1.MainWindow.textBox1'
I resolved this error by writing the following:
//MainWindow.textBox1.Text = ""; //Error 1
((MainWindow)Application.Current.MainWindow).textBox1.Text = "";//This is OK!
This was suggested by Rytis I
It seems like it should be simple enough, but im having trouble wrapping my brain around it. Normally you would declare an object in one of a couple ways
ClassName a;
a = new ClassName();
or
ClassName a = new ClassName();
etc...
but since you're explicitly declaring these at compile time i get confused when Im supposed to code this to happen at runtime. What I want to do is have a new instance of the Class instantiated when a button is clicked. But what I'm not grasping here is how is the object name going to be named if this is happening on button click?
Even worse, Objects don't have a Name at all.
The variable you are naimg is the reference to the object.
It matters what you decide the object will belong to:
void ButtonClick_H1(...)
{
ClassName a; //local variable
a = new ClassName(); // object belongs to this method
}
private ClassName anObject; // class field
void ButtonClick_H2(...)
{
anObject = new ClassName(); // object belongs to 'this' Form
}
public partial class Form1
{
Classname myClass;
public void Button1_Click(...)
{
myClass = new Classname();
}
}
?
Well, you create the object using the code you showed above, and that will be the new instance of your Class. If you declared a inside the scope of the method it will cease to exist after the method (unless there are external references to it), but if you declare it outside the method as a class variable it will stay until the class is destroyed.
In exactly the same way as you would usually name an object.
You need to hook into the button's Click event:
this.Button.Click += new RoutedEventHandler(Button_Click);
Then use something like
private void Button_Click(object sender, RoutedEventArgs e)
{
ClassName a = new ClassName();
}