C# WPF passing value between windows2 to windows1 - c#

First off, I'm a beginner in object oriented programming in which I'm currently finishing my final c# project.
BRIEF rundown, I have made a library class(dll) which I made it for a console application. This was my first project and then for this project I have to reuse the dll for a WPF application. I adapted my code for WPF.
I have a MainWindows for login, windows1 where the main program is working and calling the dll( collection base classes, specific name such has artist, curator and art).
My issue is that I have to use windows2 (study purpose) to sell an art. I call the dll class method which accepts 2 parameters such as (string IDArt, double SellPrice).
The mistake I did was to recreate a new instance of gallery in windows2.
I understand that I have to somehow send my(this) instance to windows2 and then retrieve the change to windows1.
I'm wondering how should I approach this issue. Please be advised that I understand c# from what I learned but i'm so far from truly knowing it and mastering it. Thanks in advance!

Since C# is object-oriented, the right way to do this thing would be to create an instance of your Collection class in a lower abstract layer than a window itself (since you plan to reuse the same collection in more than one window) - for example, statically in the global App context - and then use data binding to synchronize the collection between your windows. (For this to work as expected, in real time, your Collection class needs also to implement IObservable and INotifyPropertyChanged to inform the window's context that it needs to be refreshed with new elements.)

There are so many ways to do this, I tell you some of them..
If you want to access MainWindow fields or properties from elsewhere, you can do it like this:
In Window2:
//Calling MainWindow from Window2
var form = App.Current.MainWindow as ManinWindow;
form.textBox1.Text = "My Art";
MessageBox.Show(form.textBox1.Text);
or you can pass arguments from you Window1 to Window2 like this:
//Window 1
private void btnShowWindow2_Click(object sender, RoutedEventArgs e)
{
var form = new Window2("My Art", 100);
form.Show();
}
//Window 2 Constructor
public Window2(string ArtName, int Price)
{
MessageBox.Show("ArtName: " + ArtName + "\nPrice: " Price.ToString() + " dollars");
}
or
//Window1
private void btnShowWindow2_Click(object sender, RoutedEventArgs e)
{
var form = new Window2()
{
Price = 200,
ArtName = "My Art"
};
form.Show();
}
//Window2
public string ArtName {get; set;}
public int Price {get; set;}
private void Window2_Loaded(object sender, RoutedEventArgs e)
{
MessageBox.Show("ArtName: " + ArtName + "\nPrice: " Price.ToString() + " dollars");
}

probably the easiest way to do this would be to use the application's settings, also one of my favorite ways, go to "Project\WpfApp1 Properties" and go to "Settings" tab, there you can create your settings, create 1 setting name it "IDArt" and set it to a string type and another setting name it "SellPrice" and set it to double type.
now to access these settings all youhave to do is use this code:
WpfApp1.Properties.Settings.Default.IdArt;,
WpfApp1.Properties.Settings.Default.SellPrice;

Related

How to set a WinForm text property using string values in a private static void function

I am trying to incorporate some third party C# example code into my program. The third party code is part of a WinForms NET 4.6.2 application that scans devices on a COM port.
In my case, I want to insert a line (or two) of code within a method private static void PortStatusCallback(). My added code is designed to populate some text boxes on my Form1 with some of the variable values in PortStatusCallback(). The method in full is below; my proposed addition is the single line myPortname.Text = portname;. This addition returns the error message An object reference is required for the non-static field, method, or property 'Form1.myPortname'
Please can anyone suggest a way to access fields from a static method? I am new to C# programming so I would be grateful if you could write out the code for me. Thank you.
private DLL.PortStatusCallbackFuncPtr _PortStatusInstance = new DLL.PortStatusCallbackFuncPtr(PortStatusCallback); // Allocated to prevent garbage collection
private static void PortStatusCallback([MarshalAs(UnmanagedType.LPStr)] String portname, DLL.PortStatusTypes status, byte curScanAdr, byte maxScanAdr, byte foundType)
{
string statusMsg = "\r\nPortInfo Callback: " + portname + " status:" + status.ToString() + " curScanAdr:" + curScanAdr.ToString() + " maxScanAdr:" + maxScanAdr.ToString() + " foundType:" + foundType.ToString("X2");
myPortname.Text = portname; // this line is added by me and throws up a CS0120 error.
MyStatusBox.Invoke((MethodInvoker)delegate () { MyStatusBox.AppendText(statusMsg); });
Console.Write(statusMsg);
}
This answer assumes that your Form1 class represents the main form for your application; that one instance of the class is created in Program.cs, that no other instances are ever created, and when you close the form, the app goes away (i.e., a typical WinForms app).
Create a semi-private property:
Private static Form1 CurrentForm { get; private set; }
In the Form1 constructor (or in the Load handler), do the following:
CurrentForm = this;
Now, the expression Form1.CurrentForm will resolve to your main form (from anywhere in your application).
Finally change the line that is erroring on you to:
CurrentForm.myPortname.Text = portname;
Try using the static modifier like this:
private static DLL.PortStatusCallbackFuncPtr _PortStatusInstance = new DLL.PortStatusCallbackFuncPtr(PortStatusCallback); // Allocated to prevent garbage collection

use PictureBox from another class c#

I hope my question will be clear
In Form1.cs i have PictureBox named: ico_ok
i would like to use this PictureBox in my new class that i bulit.
when i start typing ico... nothing appears.
what is the way to use this object in another class?
here the code:
public void button2_Click(object sender, EventArgs e)
{
lbl_check.Visible = true;
btn_continue.Visible = false;
txtbox_cusnumber.Enabled = false;
string userID = (txtbox_cusnumber.Text.ToString());
CheckOUinADexist checkou = new CheckOUinADexist(userID);
}
after that look at the new class:
namespace ChekingOUinActiveDirectory
{
class CheckOUinADexist
{
public CheckOUinADexist(string userID)
{
//this place i would like to use ico_ok
}
}
}
Thank you for helping.
Maayan
The simplest approach is probably to provide that class with the dependency on the PictureBox:
public CheckOUinADexist(string userID, PictureBox pbox)
{
pbox.[your code]
}
Then supply it when calling the method:
CheckOUinADexist checkou = new CheckOUinADexist(userID, ico_ok);
Whether or not this is the ideal approach depends on what you're going to be doing with that PictureBox inside that object, how portable that object needs to be across technology platforms, etc.
In general you don't want UI elements to permeate into non-UI logic. If CheckOUinADexist is a UI-bound class and exists solely to help the UI, then this isn't a problem. If it's part of business logic then you wouldn't want to couple that logic with the UI technology. Instead, you'd likely pass it the data needed from the PictureBox, but not the PictureBox itself.
This all depends a lot on the overall architecture of what you're trying to achieve here, which we don't know.
Basically you'd give the target class a reference to the "shared data" -- picture box in this case.
class CheckOUinADexist
{
PictureBox _picBox
public CheckOUinADexist(string userID, PictureBox picBox)
{
//this place i would like to use ico_ok
_picBox = picBox;
_picBox.myAction();
}
}
Whether you want to actually stored Picturebox as a field (as opposed to just use a parameter) depends on whether you need access to the field throughout the lifetime of the instance(s) or whether it is just needed for object construction. If you are not sure, you are safer (IMHO) just storing a reference in a field. Make further uses of it a lot easier.

Why Windows Form TextBox won't update from outside class?

Newbie here. I'm running Visual Studio C# Express 2008. I have two Windows Forms, each with a TextBox. The textboxes update within the same class but not as the result of a invoked method from outside the class. I need to be able to update tbRooms.Text when the UpdateListOfRooms() method is invoked. I've outlined the problem in pseudo-code below. I appreciate your help!
fLocations.cs
fLocations_Load()
{
this.tbLocations.Text = Properties.Settings.Default.LocationID + " locationsLoad"; --updates
}
dgvLocations_SelectionChanged()
{
var rooms = new fRooms();
rooms.tbRooms.Text = Properties.Settings.Default.LocationID + " locationssSelectionChanged"; --updates
rooms.UpdateListOfRooms();
}
fRooms.cs
fRooms_Load()
{
this.tbRooms.Text = Properties.Settings.Default.LocationID + " roomsLoad"; --updates
}
UpdateListOfRooms()
{
this.tbRooms.Text = Properties.Settings.Default.LocationID + " roomsUpdateListOfRooms"; --does NOT update; still says "roomsLoad"
}
Updated 8/20/14:
I've been a busy bee :) I read all the parts of the tutorial by #jmcilhinney and decided to approach this by including references to the two forms, Locations and Rooms, in the MainMenu class that launches them:
(MainMenu.cs) Instances of Locations and Rooms are created. In the constructor, 'rooms' is passed to the 'locations' instance and both forms are shown.
(Locations.cs) Another Rooms instance is created at class scope so it can be seen by all methods of the class. In the constructor, this instance is set to the one being passed by MainMenu which means that this class is working with the same instance created in MainMenu. When the user changes the selection on dgvLocations, the 'dgvLocations_SelectionChanged' event is fired which invokes the Rooms.UpdateRooms method.
(Rooms.cs) The 'UpdateRooms' method displays a new set of rooms based on the passed value of 'locationID'.
This link was helpful. Visual C# - Access instance of object created in one class in another.
public partial class MainMenu : Form
{
Locations locations;
Rooms rooms;
public MainMenu()
{
rooms = new Rooms();
locations = new Locations(rooms);
locations.Show();
rooms.Show();
InitializeComponent();
}
}
public partial class Locations : Form
{
Rooms rooms;
public Locations(Rooms r)
{
rooms = r;
InitializeComponent();
}
private void Locations_Load(object sender, EventArgs e)
{
// Populate this.dgvLocations using SQL query.
}
private void dgvLocations_SelectionChanged(object sender, EventArgs e)
{
// Update the rooms instance with current locationID.
rooms.UpdateRooms(dgvLocations.CurrentCell.Value.ToString());
}
}
public partial class Rooms : Form
{
public Rooms()
{
InitializeComponent();
}
private void Rooms_Load(object sender, EventArgs e)
{
// Populate this.dgvRooms using SQL query.
}
public void UpdateRooms(string locationID)
{
// Update dgvRooms based on user changing the locationID in dgvLocations
}
}
In the first code snippet, you create a new fRooms object but you never call its Show or ShowDialog method, which means that you never display it to the user. That means that any changes you make to that form will not be seen. Presumably the user can see an fRooms object though, but you are not making any changes to that one.
Consider this. Let's say that I give you a note pad and you open it and look at the first page. Let's say that I now buy a new note pad and write on the first page of it. Would you expect to see the words I wrote magically appear on the page in front of you? Of course not. We both are holding a note pad but they are two different note pads. You're looking at one and I'm writing on the other, so you won;t see what I write.
The same goes for your forms. They are both fRooms objects but they are two different fRooms objects. Changes you make to one will not affect the other. If you want the user to see the changes you make then you must make those changes to the fRooms object that the user is looking at.

C# Take combobox item from one form and add its name as text to another

Ok so I'm attempting to create a simple game. In a nutshell it's a resource management game where the player will attempt to manage a thieves guild. In regards to running missions I've created a Thief class, a new instance of which is created when a new thief is recruited. I have coded within the thief class the ability to gain experience and level up.
Here's my specific problem:
I want the player to be able to select which thief/thieves to send on a mission. I have thought about it and figured that opening a new form and populating it with checkboxes is the easiest way to allow this. These checkboxes will be related to a List<thief> of thieves, the player then checks the thieves s/he wants to send and these are then stored in another List<thief> and passed on to the run mission function.
I've built a separate project with the intention of testing and playing around with this before putting it into the main program. The test project consists of two forms: The first (frmMain) with a textbox to hold the selected options and a button to open the second form (frmSelect). Currently I can open and populate the second form (frmSelect) but when I try to add the checked options to the textbox I simply...well can't.
So far I have tried directly accessing the textbox by typing frmMain.txtOptionsDisplay in the cs file of frmSelect but it causes the following error:
An object reference is required for the non-static field, method or
property
I tried to create a new form in frmSelect and make it equal to the active instance of frmMain with: Form frmTemp = frmMain.ActiveForm; and then alter the textbox using frmTemp as a go-between but that produced the error:
'System.Windows.Forms.Form' does not contain a definition for
'txtOptionsDisplay'.
Having searched both google and stackoverflow forums I've encountered answers that I either have never heard of (Threading) or answers that I kind've recognise but can't interpret the code pasted to make it relevant to my problem (delegates).
Any advice or pointers would be fantastic.
EDIT:
frmMain code:
public frmMain()
{
InitializeComponent();
selections.Add("Option 1");
selections.Add("Option 2");
}
private void btnClick_Click(object sender, EventArgs e)
{
frmSelectOptions.Show();
int length = selections.Count();
for (int i = 0; i < length; i++)
{
CheckBox box = new CheckBox();
box.Text = selections[i];
box.AutoSize = true;
box.Location = new Point(50, 50*(i+1));
frmSelectOptions.grpControls.Controls.Add(box);
}
}
public void updateText(string option)
{
txtOptionsDisplay.Text += option;
}
}
frmSelect code:
public List<CheckBox> selectedOptions = new List<CheckBox>();
Form frmTemp = frmMain.ActiveForm;
public frmSelect()
{
InitializeComponent();
}
private void btnSelect_Click(object sender, EventArgs e)
{
foreach (CheckBox box in grpControls.Controls)
{
if (box.Checked == true)
selectedOptions.Add(box);
}
this.Hide();
}
}
I hope this formats correctly... I'm kinda new and don't know how to indent. Oh look there's a preview...
Does this help?
Your problem is that controls defined within a form by default receive the private access identifier. Hence you could just add a property along the lines of
public ControlType ProxyProperty {
get {
return txtOptionsDisplay;
}
}
Besides from that you should think about wether what you're trying is actually a good solution. Manipulating forms from one to another will become a huge clusterfuck in terms of maintenance later on.
I'd suggest using the Singleton pattern for your frmMain. This will help safeguard you from accidentally launching another instance of frmMain and at the same time, will give you access to frmMain's objects. From there, you can either write accessors to Get your txtOptionsDisplay or you can make it public. Below is an example:
public class frmMain
{
private static frmMain Instance = null;
private static object LockObj = new object();
public static frmMain GetMain()
{
// Thread-safe singleton
lock(LockObj)
{
if(Instance == null)
Instance = new frmMain();
return Instance;
}
}
public string GetOptionsDisplayText()
{
return txtOptionsDisplay.Text;
}
}
public class frmSelect
{
private void frmSelect_Load(object sender, EventArgs e)
{
// Set whatever text you want to frmMain's txtOptionsDisplay text
txtDisplay.Text = frmMain.GetMain().GetOptionsDisplayText();
}
}
If you do go this route, don't forget to update Program.cs to use frmMain's singleton.
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// Application.Run(new frmMain()); - Old method
Application.Run(frmMain.GetMain());
}

Passing objects between classes in Windows Phone/C#

I'm new to Windows Phone and C#, enjoying the change from Objective-C and Java.
I cant find the way to pass an object from one class to another. I came across some sample code looking on MSDN but I tink that maybe its not applicable for what I need.
private void meetingList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (meetingList.SelectedIndex != -1)
{
Meeting aMeeting = (Meeting)meetingList.SelectedItem;
this.NavigationService.Navigate(new Uri("/MeetDetails.xaml", UriKind.Relative));
ApplicationBar.IsVisible = true;
}
}
How can I pass my Meeting Object 'aMeeting' into my MeetDetails class so that I can display all the details to the user.
I know I can break it down, and pass in all the vars from the 'aMeeting' by using something like this:
this.NavigationService.Navigate(new Uri("/MeetDetails.xaml?Meeting=" +
aMeeting.meetName + "&TheDate=" +
aMeeting.meetDate, UriKind.Relative));
Is there something I've missed? Are there alternative ways you guys would recommend?
Many Thanks,
-Code
What you've posted is a good way of transferring simple data about the place. However it becomes a pain when you have to pass a complex object between pages.
The recommended way is to use the MVVM pattern (from wikipedia and MSDN). This gives you a way to separate the View from everything else by making use of data binding. The best tutorials I have seen is to watch the videos on MSDN.
var t1 = App.Current as App;
t1.SSIDToken = stData1SSID;
t1.CSRFToken = stData1CSRF;
this works real good, just make the members u need in the app.cs file
(here it was :
public string SSIDToken {get; set;}
public string CSRFToken {get; set;}
Then create the top code to create a var to serve as temp buffer.
If you want to get back the values use the same code :
var t1 = App.Current as App;
thisisatextbox.Text = t1.SSIDToken;
thisisalsoatextbox.Text = t1.CSRFToken;
Further info ;
http://www.eugenedotnet.com/2011/07/passing-values-between-windows-phone-7-pages-current-context-of-application/
EDIT: After a couple of months of experience, noticed you can add
public static new App Current
{
get { return Application.Current as App; }
}
In the App.xaml (In the public class App) to be able to call upon App.Current without having to declare it every single time!
Now you can use App.Current.CSRFToken = "" || string CSRFTk = App.Current.CSRFToken;
You might want to consider a manager class with properties which could store your current Meeting object. This would then be set in your SelectionChanged event handler and then accessed in your MeetDetails page. The manager class is defined externally to your pages so that it can be accessed from all your pages.

Categories