Access class from another form - c#

I'm struggling to get a class from a different form without making it static, here's what I want to do:
//First form
public partial class SetupScreen : Form
{
Control myObject;
public Battleship myBattleship;
public SetupScreen()
{
InitializeComponent();
//Create Class Object
myBattleship = new Battleship();
}
}
//Launch second form
public partial class GameScreen : Form
{
Control myObject;
Battleship myBattleship;
Battleship fredBattleship;
public GameScreen()
{
InitializeComponent();
//Get the class
myBattleship = SetupScreen.myBattleship;
}
}
I keep getting the error "an object reference is required for the non-static field, method or property"
I want the class to be accessible by the whole form, not just a single method therefore I don't want to pass it through each time because this is a hassle
I don't want to make the class static since it cannot be erased, how would I go about doing this?

You are getting this error because you are trying to access a non-static field in a static manner.
Where do you instantiate SetupScreen and GameScreen?
Why not something like this:
public partial class SetupScreen : Form
{
private Control myObject;
public Battleship myBattleship;
private GameScreen gameScreen;
public SetupScreen()
{
InitializeComponent();
//Create Class Object
myBattleship = new Battleship();
gameScreen = new GameScreen(this);
}
}
public partial class GameScreen : Form
{
private Control myObject;
private Battleship myBattleship;
private Battleship fredBattleship;
private SetupScreen setupScreen;
public GameScreen(SetupScreen setupScreen)
{
InitializeComponent();
this.setupScreen = setupScreen;
myBattleship = this.setupScreen.myBattleship;
}
}
Of course, this will only work if you can instantiate GameScreen in SetupScreen. I could give you a better answer if you tell me where/how you are "launching" these forms.

You could pass a reference of your first form to your second form, or (what I would do), create a public Battleship property on your second form and pass your object that way.
//First form
public partial class SetupScreen : Form
{
Control myObject;
public Battleship myBattleship;
public SetupScreen()
{
InitializeComponent();
//Create Class Object
myBattleship = new Battleship();
Form gameForm = new GameScreen(); // New form object
gameForm.MyBattleship = myBattleship; // Set property
gameForm.Show(); // Show form
}
}
//Second form
public partial class GameScreen : Form
{
Control myObject;
Battleship fredBattleship;
public BattleShip MyBattleship { set; get; }
public GameScreen()
{
InitializeComponent();
}
}

you must use singleton pattern.
so your code must be like this:
//First form
public partial class SetupScreen : Form
{
public static SetupScreen setupScreenFrm;
Control myObject;
public Battleship myBattleship;
public SetupScreen()
{
setupScreenFrm=this;
InitializeComponent();
//Create Class Object
myBattleship = new Battleship();
}
}
//Launch second form
public partial class GameScreen : Form
{
Control myObject;
Battleship myBattleship;
Battleship fredBattleship;
public GameScreen()
{
InitializeComponent();
//Get the class
SetupScreen ssFrm=SetupScreen.setupScreenFrm;
myBattleship = ssFrm.myBattleship;
}
}
and first of all, in the start of your app, create an instant of SetupScreen form.
now you can access to SetupScreen in anywhere.

Related

Cannot share a view into mutiple component

I got a task that need to share camera view from a webcam into 2 Window. I've tried using singleton for create camera view only one time. The problem is that created instance can not share between 2 class. I'm now really confused. What am I doing wrong here?
MainWindow class
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
ReceptionMainWindow receptionMainWindow = new ReceptionMainWindow();
CustomerMainWindow customerMainWindow = new CustomerMainWindow();
receptionMainWindow.Show();
customerMainWindow.Show();
this.Hide();
}
}
Receptionist class
public partial class ReceptionMainWindow : Window
{
public ReceptionMainWindow()
{
InitializeComponent();
ReceptionWindowHoler.Content = CameraPage.getInstance();
}
}
Customer Class
public partial class CustomerMainWindow : Window
{
public CustomerMainWindow()
{
InitializeComponent();
CustomerWindowHoler.Content = CameraPage.getInstance();
}
}
private static CameraPage instance;
Camera class
public CameraPage()
{
InitializeComponent();
//DataContext = CameraViewModel.getInstance();
this.DataContext = this;
GetVideoDevices();
}
public static CameraPage getInstance()
{
if (instance == null)
instance = new CameraPage();
return instance;
}
You could create a Bitmap from the camera view and share it via events to the two other windows.
Take this answer as a workaround. There must be a better way.

How do i specify that i want to change a label on a particular form? [duplicate]

I have a winform called Form1 and a textbox called textBox1
In the Form1 I can set the text by typing:
textBox1.text = "change text";
Now I have created another class. How do I call textBox1 in this class?
so I want to change the text for textBox1 in this class.
How can I access the Form1 from this new class?
I would recommend that you don't. Do you really want to have a class that is dependent on how the text editing is implemented in the form, or do you want a mechanism allowing you to get and set the text?
I would suggest the latter. So in your form, create a property that wraps the Text property of the TextBox control in question:
public string FirstName
{
get { return firstNameTextBox.Text; }
set { firstNameTextBox.Text = value; }
}
Next, create some mechanism through which you class can get a reference to the form (through the contructor for instance). Then that class can use the property to access and modify the text:
class SomeClass
{
private readonly YourFormClass form;
public SomeClass(YourFormClass form)
{
this.form = form;
}
private void SomeMethodDoingStuffWithText()
{
string firstName = form.FirstName;
form.FirstName = "some name";
}
}
An even better solution would be to define the possible interactions in an interface, and let that interface be the contract between your form and the other class. That way the class is completely decoupled from the form, and can use anyting implementing the interface (which opens the door for far easier testing):
interface IYourForm
{
string FirstName { get; set; }
}
In your form class:
class YourFormClass : Form, IYourForm
{
// lots of other code here
public string FirstName
{
get { return firstNameTextBox.Text; }
set { firstNameTextBox.Text = value; }
}
}
...and the class:
class SomeClass
{
private readonly IYourForm form;
public SomeClass(IYourForm form)
{
this.form = form;
}
// and so on
}
I was also facing the same problem where I was not able to appendText to richTextBox of Form class. So I created a method called update, where I used to pass a message from Class1.
class: Form1.cs
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
_Form1 = this;
}
public static Form1 _Form1;
public void update(string message)
{
textBox1.Text = message;
}
private void Form1_Load(object sender, EventArgs e)
{
Class1 sample = new Class1();
}
}
class: Class1.cs
public class Class1
{
public Class1()
{
Form1._Form1.update("change text");
}
}
You can change the access modifier for the generated field in Form1.Designer.cs from private to public. Change this
private System.Windows.Forms.TextBox textBox1;
by this
public System.Windows.Forms.TextBox textBox1;
You can now handle it using a reference of the form Form1.textBox1.
Visual Studio will not overwrite this if you make any changes to the control properties, unless you delete it and recreate it.
You can also chane it from the UI if you are not confortable with editing code directly. Look for the Modifiers property:
public partial class Form1 : Form
{
public static Form1 gui;
public Form1()
{
InitializeComponent();
gui = this;
}
public void WriteLog(string log)
{
this.Invoke(new Action(() => { txtbx_test1.Text += log; }));
}
}
public class SomeAnotherClass
{
public void Test()
{
Form1.gui.WriteLog("1234");
}
}
I like this solution.
You will need to have some access to the Form's Instance to access its Controls collection and thereby changing the Text Box's Text.
One of ways could be that You can have a Your Form's Instance Available as Public or More better Create a new Constructor For your Second Form and have it receive the Form1's instance during initialization.
Define a property of the form like, then use this in other places it would be available with the form instance
public string SetText
{
get { return textBox1.Text; }
set { textBox1.Text = value; }
}
If your other class inherits Form1 and if your textBox1 is declared public, then you can access that text box from your other class by simply calling:
otherClassInstance.textBox1.Text = "hello world";
Use, a global variable or property for assigning the value to the textbox, give the value for the variable in another class and assign it to the textbox.text in form class.
I Found an easy way to do this,I've tested it,it works Properly.
First I created a Windows Project,on the form I Inserted a TextBox and I named it textBox1
then I inserted a button named button1,then add a class named class1.
in the class1 I created a TextBox:
class class1
{
public static TextBox txt1=new TextBox(); //a global textbox to interfece with form1
public static void Hello()
{
txt1.Text="Hello";
}
}
Now in your Form Do this:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
class1.txt1=textBox1;
class1.Hello();
}
}
in the button1_Click I coppied the object textBox1 into txt1,so now txt1 has the properties
of textBox1 and u can change textBox1 text in another form or class.
Form1 form = new Form1();
form.textBox1.Text = "test";
I tried the examples above, but none worked as described. However, I have a solution that is combined from some of the examples:
public static Form1 gui;
public Form1()
{
InitializeComponent();
gui = this;
comms = new Comms();
}
public Comms()
{
Form1.gui.tsStatus.Text = "test";
Form1.gui.addLogLine("Hello from Comms class");
Form1.gui.bn_connect.Text = "Comms";
}
This works so long as you're not using threads. Using threads would require more code and was not needed for my task.
I used this method for updating a label but you could easily change it to a textbox:
Class:
public Class1
{
public Form_Class formToOutput;
public Class1(Form_Class f){
formToOutput = f;
}
// Then call this method and pass whatever string
private void Write(string s)
{
formToOutput.MethodToBeCalledByClass(s);
}
}
Form methods that will do the updating:
public Form_Class{
// Methods that will do the updating
public void MethodToBeCalledByClass(string messageToSend)
{
if (InvokeRequired) {
Invoke(new OutputDelegate(UpdateText),messageToSend);
}
}
public delegate void OutputDelegate(string messageToSend);
public void UpdateText(string messageToSend)
{
label1.Text = messageToSend;
}
}
Finally
Just pass the form through the constructor:
Class1 c = new Class1(this);
Form frm1 = new Form1();
frm1.Controls.Find("control_name",true)[0].Text = "I changed this from another form";
// Take the Active form to a form variable.
Form F1 = myForm1.ActiveForm;
//Findout the Conntrol and Change the properties
F1.Controls.Find("Textbox1", true).ElementAt(0).Text= "Whatever you want to write";
What about
Form1.textBox1.text = "change text";
note:
1. you have to "include" Form1 to your second form source file by
using Form1;
textBox1 should be public

WPF- How can i use a List that i declare and fill in my MainWindow in a Usercontrol?

Hi i need to be able to use a list from my Main Window in a Usercontrol i need to be able to edit and read from it in various Usercontrols.
MainWindow:
public partial class MainWindow : Window
{
public List<Termin> termine = new List<Termin>();
public MainWindow()
{
InitializeComponent();
}
}
Usercontrol:
public partial class KalenderAnsicht : UserControl
{
public KalenderAnsicht()
{
InitializeComponent();
}
private void SomeMethod()
{
//i need to be able to use the list here
}
}
You need to get a reference to the MainWindow one way or another. The easiest way to do this is probably to use the Application.Current.Windows property:
private void SomeMethod()
{
var mw = Application.Current.Windows.OfType<MainWindow>().FirstOrDefault();
List<Termin> termine = mw.termine;
//...
}
You could also consider making termine static:
public partial class MainWindow : Window
{
public static List<Termin> termine = new List<Termin>();
public MainWindow()
{
InitializeComponent();
}
}
...and access it directly without a reference to an instance of MainWindow:
private void SomeMethod()
{
List<Termin> termine = MainWindow.termine;
//...
}

AccessibleObject implementation for custom controls

I have a very simple controls library for Windows Forms and I am getting problems to implement accessibility.
I have a very simple Form with a member that contains a list of controls of my library, and I have overriden the CreateAccessibilityInstance:
public partial class Form1 : Form
{
protected override AccessibleObject CreateAccessibilityInstance()
{
return new AccessibleForm(this);
}
public MyContainer MyContainer;
public Form1()
{
InitializeComponent();
MyContainer = new MyContainer();
MyContainer.Controls.Add(new MyButton());
}
}
The AccessibleForm class looks like:
public class AccessibleForm: Control.ControlAccessibleObject
{
private Form1 form1;
public AccessibleForm(Form1 owner):base(owner)
{
this.form1 = owner;
}
public override AccessibleObject GetChild(int index)
{
return this.form1.MyContainer.Controls[index].AccessibilityObject;
}
public override int GetChildCount()
{
return this.form1.MyContainer.Controls.Count() ;
}
}
MyContanier and MyButton classes inherits from BaseControl, they are very easy:
public class BaseControl : Control
{
protected override AccessibleObject CreateAccessibilityInstance()
{
return new AccessibleObject();
}
}
public class MyContainer:BaseControl
{
public List<BaseControl> Controls { get; set; }
public MyContainer()
{
this.Controls = new List<BaseControl>();
}
}
public class MyButton:BaseControl
{
}
The point is that when I run the UIVerify tool to see if my controls are generating the correct structure I can not see them:
Another point is, that if I modify the GetChild method from AccessibleForm class in this way:
public override AccessibleObject GetChild(int index)
{
return new AccessibleObject();
////return this.form1.MyContainer.Controls[index].AccessibilityObject;
}
I can see a node on the UIVerify:
But modifying the GetChild method to return a custom accessible object it shows me nothing.
Why are not my controls on the tree?
I do not know what I am missing.
Override Name,value,Role in AccessibleForm class

winforms, loop through components

I am trying to loop through components on a form, but components seems to be null.
So, how do I loop through components (NOT CONTROLS) on a form ?
public partial class FormBase : Form
{
public FormBase()
{
InitializeComponent();
FixVisualDesignerIssues();
}
protected void FixVisualDesignerIssues()
{
// this.components is always NULL ????????
foreach (var comp in this.components.Components.OfType<BindingSource>())
{
((BindingSource)comp).do something, whatever
}
}
EDITED as requested
public partial class FormBaseList : Test_app.FormBase
{
public FormBaseList()
{
InitializeComponent();
}
public partial class FormBaseDetail : Test_app.FormBase
{
public FormBaseDetail():base()
{
InitializeComponent();
gttDataGridView1.AutoGenerateColumns = false;
}
If you are creating the BindingSource the following way, only then it will be contained in the components container.
BindingSource bindingSource1 = new BindingSource(components);
If you are using any other way to create the binding source, there will be nothing in the components container.

Categories

Resources