I made a program that essentially contained 150 actions, all in the first form. It has become a nightmare to manage and a friend recommended splitting groups of actions into separate classes.
Ideally going from: Do {1,2,3,4,5} to Do {A,B} where A is {1,2,3} and B is {4,5}.
To practice, I decided to try to work 2 classes:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
public void button_Click(object sender, RoutedEventArgs e)
{
if (checkBox1.IsChecked == true)
{
checkTrue();
}
else
{
checkFalse();
}
}
public void checkTrue()
{
textBox.Text = "checkbox was checked";
}
public void checkFalse()
{
textBox.Text = "unchecked :(";
}
}
How would I go about changing this to a set it as a new class to be called upon?
When creating a new class "checkBool", I wrote the following in a new .cs:
class checkBool
{
public void checkTrue()
{
textBox.Text = "checkbox was checked";
}
public void checkFalse()
{
textBox.Text = "unchecked :(";
}
}
However, the textbox is no longer recognized. How can I make this new class understand the reference?
The textbox is not recognized by the checkbool instance because it doesn't know about it.
One quick way to "let it know about it" is passing the textbox as a parameter to the checkTrue() and checkFalse() operations, like this:
class checkBool
{
public void checkTrue(TextBox textBox)
{
textBox.Text = "checkbox was checked";
}
public void checkFalse(TextBox textbox)
{
textBox.Text = "unchecked :(";
}
}
So the button click handler would be:
public void button_Click(object sender, RoutedEventArgs e)
{
checkBool cb = new checkBool();
if (checkBox1.IsChecked == true)
{
cb.checkTrue(textbox);
}
else
{
cb.checkFalse(textbox);
}
}
Keep in mind that by doing this you are introducing a dependency to your class checkBool (It depends to TextBox now).
Related
I made a class so when the user selects item from listbox it uninstalls that item, except the problem is I can't access the list box. I tried public aswell, but in the code of form1.cs the only thing clostest to that list box is
keep in mind name of listbox is ProgramslistBox
Ok guys I re edited this post;
private void button1_Click(object sender, EventArgs e)
{
if(ProgramsListbox.SelectedIndex == -1)
{
MessageBox.Show("Please select an item to uninstall!");
}
else
{
ProgramsListbox_SelectedIndexChanged("",EventArgs.Empty);
}
}
this code is the FORM1.CS class, and I have another class called UninstallItem.cs is where I want my code to be, this below is my other class
namespace PC_TECH_Registery_Cleaner
{
class UninstallItem
{
public void uninstallSelectedItem()
{
Form1 c = new Form1();
}
}
}
And this below is still in my FORM1.CS class, I was experimenting with it :
public void ProgramsListbox_SelectedIndexChanged(object sender, EventArgs e)
{
//this will access the Uninstall item class so we can uninstall selected item.
UninstallItem c = new UninstallItem();
c.uninstallSelectedItem();
}
Within your Form1.cs create instance of UnIstallItem class and use it. Then on Button Click call "RemoveSelected" method of UnInstaItem class by passing programsListBox to it and it should remove the selected item.
public class Form1:Form
{
ListBox ProgramsListbox;
UninstallItem unistall;
public Form1(){
InitializeComponent();
uninstall = new UninstallItem();
button1.Click+= button1_Click;
}
void button1_Click(object sender, EventArgs e){
unistall.RemoveSelected(ProgramsListbox);
}
}
Then in your external class;
public class UninstallItem{
public UninstallItem{}
public void RemoveSelected(ListBox list)
{
if(list.SelectedIndex==-1)
{
MessageBox.Show("Please Select Item from List");
return;
}
list.Items.RemoveAt(list.SelectedIndex);
}
}
The 2 easy ways to think about this are either
Call the method in your class from the event handler in your form
Have a method on your class which matches the signature of an event handler, and subscribe to the event.
The first requires no major change
private MyClass myClass = new MyClass();
public void ProgramsListbox_SelectedIndexChanged(object sender, EventArgs e)
{
myClass.DoSomething();
}
The second requires your class to have a specific method that matches the signature of that event handler currently in your form
public class MyClass
{
public void DoSomething(object sender, EventArgs e)
{
var listBox = (ListBox)sender;
// read selected index perhaps, or selected item maybe
}
}
And then in your form
private MyClass myClass = new MyClass();
protected override void OnLoad(EventArgs e)
{
this.ProgramsListBox.SelectedIndexChanged += myClass.DoSomething;
}
I have an issue with a custom event i have created. I have made a Usercontrol that looks the following:
public partial class UCListView : UserControl {
public UCListView() {
InitializeComponent();
}
public event EventHandler SubmitClick;
public event EventHandler MouseButtonUpEvent;
private void SubmitButton_OnClick(object sender, RoutedEventArgs e) {
if (SubmitClick != null)
SubmitClick(this, e);
}
private void MouseButtonUp(object sender, RoutedEventArgs e) {
if (MouseButtonUpEvent != null) {
MouseButtonUpEvent(this, e);
}
}
}
Here is the MouseButtonUp event i have.
The following is where i listen to the event:
public partial class RoundsteelWindow : WindowControls {
private UCListView uc;
public RoundsteelWindow() {
InitializeComponent();
uc = new UCListView();
uc.SubmitClick += new EventHandler(ButtonPressed);
uc.MouseButtonUpEvent += new EventHandler(MousePressed);
stkTest.Children.Add(uc);
base.Test<RoundSteel>(uc, "Roundsteel");
}
}
Here is the WindowControls, where the MousePressed method can be seen. This is the same as the code snippet beneath this code. Really don't see the issue:
public abstract class WindowControls : Window {
public IMaterialWith14Elements _ReturnObject { get; set; }
public double amount { get; set; }
private UCListView _uc;
public void Test<T>(UCListView uc, string type) where T: IMaterialWith14Elements, new() {
_uc = uc;
List<T> test = MaterialLogic.GetList(type) as List<T>;
foreach (T material in test) {
uc.listView.Items.Add(material.Name);
}
}
private string str;
public void MousePressed(object sender, EventArgs eventArgs) {
var item = (sender as ListView).SelectedItem;
if (item != null) {
_ReturnObject = _uc.listView.SelectedItems as FlatSteel ;
str = item.ToString();
_uc.amountText.IsEnabled = true;
}
}
public void ButtonPressed(object sender, EventArgs e) {
if (!string.IsNullOrEmpty(_uc.amountText.Text)) {
amount = _uc.amountText.Text.customParseToDouble();
this.Close();
}
else {
MessageBox.Show("Indtast venligst en værdi.");
}
}
}
Now the problem is the following: With the following code it is working, but this class is not using the windowcontrols. It is called by another class which handles all of the buttons.
private void flatsteelListView_PreviewMouseLeftButtonUp(object sender, RoutedEventArgs e) {
var item = (sender as ListView).SelectedItem;
if (item != null) {
_returnObject = flatsteelListView.SelectedItems as FlatSteel;
str = item.ToString();
amountTextbox.IsEnabled = true;
FindObject(str);
}
}
The first picture shows the working window. This is where there is not used a usercontrol. Actually this is a previous issue i have worked with and got help with here on stackoverflow Help for thisissue.
The second picture is showing the next window using the usercontrol that has been created. The button event works and closes the window. Here comes then the issue, when the listview item is pressed. It is doing the same thing as on the first picture(where it works), but it is giving me a null reference, which doesn't make any sense to me. I have also checked the object sender to see if there was a difference between the sender of these two different windows.
I simply can't figure out why this is not working.
greetings darophi
Your sender is an object of UCListView class which is inherited from UserControl and you are trying to use it like ListView. So as result of operation (sender as ListView) you get null because sender is not an instance of ListView class and not inherits it.
trying to get data from the main form to form 2. The main form has a textbox
and a button. when the button is pressed it opens form 2 which will display the data entered in the main form as a series of text blocks.
However I cant get the data to transfer between the forms. the code is bellow.
can anyone help or suggest anything I can do differently?
WPF 1 main form:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void btnOpenForm_Click(object sender, RoutedEventArgs e)
{
//btnset: Takes the values contained in the text boxes and updates
//the student class
//properties.
Student.sFname = firstname.Text;
Student.sSname = secondname.Text;
Window1 details = new Window1();
details.Show();
}
WPF 2 code:
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void details_Load(object sender, EventArgs e)
{
Fname.Text = Student.sFname;
Sname.Text = Student.sSname;
}
private void Close_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
}
There are a number of ways to "pass data" between 2 classes. The easiest way is to expose property or method on Window1 and just set the text you need passed. Another way is to create a constructor on Window1 that takes in the data as parameters. Here is code that demonstrates these approaches.
public class Program
{
public static void Main(string[] args)
{
var c1 = new Class1();
c1.DoStuff();
}
}
public class Class1
{
public void DoStuff()
{
var c = new Class2("stuff");
var c2 = new Class2();
c2.AcceptStuff("stuff2");
c.Print();
c2.Print();
c2.MyData = "stuff3";
c2.Print();
}
}
public class Class2
{
private string _myData;
public Class2()
{
}
public Class2(string myData)
{
_myData = myData;
}
public string MyData
{
set { _myData = value;}
}
public void AcceptStuff(string myData)
{
_myData = myData;
}
public void Print()
{
Console.WriteLine(_myData);
}
}
Prints
stuff
stuff2
stuff3
I assume you have a class in MainWindow like:
`Public class Student
{
public static string sFname;
public static string sSname;
}`
When you click open button you are assigning values to those variable, but if you want to access them in another window mention the window name and then class name.
Check this code if its working?
`public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void details_Load(object sender, EventArgs e)
{
Fname.Text = MainWindow.Student.sFname;
Sname.Text = Mainwindow.Student.sSname;
}
private void Close_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
}`
I'm actually learning (the hard way) c# and been fighting for days with a problem :
I'm writing my first c# application with WPF (dotNet 4.0). When I click on a button, a BackgroundWorker thread is used and call a method from an external class, this way my UI don't freeze -> my method run as expected.
Then I tried to update a ListView control from thos external class to get some kind of progress (text) and I miserably failed.
I understand that I need to use a delegate and the dispatcher to update my control.
I tried to use the solution offered here How to update UI from another thread running in another class . (I cannot comment on it because of my low rep) and I miss some parts of the puzzle.
What the YourEventArgs(status) is referring to ? I just don't get the way to fire an event and pass the content back to my UI while my method is running inside the BGW.
So far I have this piece of code (Updated from answer):
namespace AppMain
{
public partial class MainWindow
{
BackgroundWorker AppWorker = new BackgroundWorker();
public MainWindow()
{
InitializeComponent();
AppWorker.WorkerSupportsCancellation = true;
AppWorker.DoWork += AppWorker_DoWork;
AppWorker.RunWorkerCompleted += AppWorker_RunWorkerCompleted;
}
private void btnLoad_Click(object sender, RoutedEventArgs e)
{
lstTest.Items.Add("Processing data...");
AppWorker.RunWorkerAsync();
}
public void AppWorker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
SetXmlData xml = new SetXmlData();
xml.ProgressUpdate += (s, evt) =>
{
Dispatcher.BeginInvoke((Action)(() =>
{
lstTest.Items.Add("this is a test : " + evt.myData); //how to retrieve the myData property from evt ?
}));
};
xml.FlushData();
}
public void AppWorker_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
if (!(e.Cancelled))
{
lstTest.Items.Add("Done");
}
else
{
MessageBox.Show("Cancelled");
}
}
}
}
SetXmlData.cs
namespace AppMain
{
public class SetXmlData
{
public event EventHandler ProgressUpdate;
//update method
public void update(object input)
{
if (ProgressUpdate != null)
ProgressUpdate(this, new YourEventArgs { myData = (string)input });
}
//calculation method
public void FlushData()
{
MessageBox.Show("this is a test !");
update("test");
}
}
public class YourEventArgs : EventArgs
{
public string myData { get; set; }
}
}
Thanks for your help.
You can simply Invoke the ProgressUpdate event from the FlushData() method.
Simply call:
If (ProgressUpdate !=null )
{
ProgressUpdate(this,new YourEventArgs())
}
this is the source instance where the event originated from.
You could just create YourEventArgs by inheriting from EventArgs class.
public class YourEventArgs : EventArgs
{
//Put any property that you want to pass back to UI here.
}
When the event gets raised in the UI:
RaiseEvent.ProgressUpdate += (s, e) =>
{
Dispatcher.BeginInvoke((Action)(() =>
{
lstTest.Items.Add("this is a test : ");
//Add items to your UI control here...
}));
};
e will be of type YourEventArgs.
On a side note, you should never touch UI thread from a diffent thread (like background worker thread in your example). Since your event-handler already does the Dispatcher.BeginInvoke, that's safe.
Also, your ProgressUpdate event should be inside of your class SetXmlData.
try get;set; Example:
Form1:
public partial class Form1 : Form
{
static public string gettext { get; set; }
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Class1.send(); //call to class function
textBox1.Text = gettext; //items.add(gettext)
}
}
Class1:
class Class1
{
static public void send()
{
Form1.gettext = "Marko"; //Set gettext to string "Marko"
}
}
I'm a newbie in c# and visual studio, but not programming in general.
I searched for answer to my question for 3 days and I found plenty of them, but for some weird reason (I'm sure I'm missing something very obvious) I cannot get it to work.
I think it's the most basic question newbies like me ask.
I have a form (Form3) with a text box and a button (I set it up is just for testing purposes).
I want to populate and read this text box from another class. I understand the most proper way to do this is to create a property in Form3.cs with GET and SET accessors. I did that but I cannot get it to work. I'm not getting any error messages, but I'm not able to set the value of the text box either. It just remains blank.
Here's my sample code:
namespace WindowsFormsApplication1
{
public partial class Form3 : Form
{
public string setCodes
{
get { return test1.Text; }
set { test1.Text = value; }
}
public Form3()
{
InitializeComponent();
}
private void Form3_Load(object sender, EventArgs e)
{ }
private void button1_Click(object sender, EventArgs e)
{
a.b();
}
}
public class a
{
public static void b()
{
Form3 v = new Form3();
v.setCodes = "abc123";
}
}
}
Can someone lend me a hand solving this?
The problem is you are setting the value to a new instance of the form. Try something like this:
public partial class Form3 : Form {
public string setCodes
{
get { return test1.Text; }
set { test1.Text = value; }
}
private A a;
public Form3()
{
InitializeComponent();
a = new A(this);
}
private void button1_Click(object sender, EventArgs e)
{
a.b();
}
private void Form3_Load(object sender, EventArgs e)
{
}
}
public class A
{
private Form3 v;
public a(Form3 v)
{
this.v = v;
}
public void b()
{
v.setCodes = "abc123";
}
}
You're creating a brand new Form3() instance.
This does not affect the existing form.
You need to pass the form as a parameter to the method.
Try this:
public partial class Form3 : Form
{
/* Code from question unchanged until `button1_Click` */
private void button1_Click(object sender, EventArgs e)
{
a.b(this);
}
}
public class a
{
public static void b(Form3 form3)
{
form3.setCodes = "abc123";
}
}
This passes the current instance of the form to the other class so that it can update the setCodes property. Previously you were creating a new form instance rather than updating the current form.
Sending form instance to other other class
Form1 objForm1=new Form1();
obj.Validate(objForm1);
Easy way to access controls in another class by modifying Controls Private to Public in the Form(Designer.cs)