I've been working a lot with WPF, and after awhile the MainWindow class becomes cluttered and unorganized. Is there a way to store all of the control events in a custom class like below? Inheriting doesn't work and i'm guessing its because it has no instance of the new class to go off of.
public partial class MainWindow : Window
{
public class ControlEvents : MainWindow //Custom class
{
private void Abutton_Click(object sender, RoutedEventArgs e)
{
...Stuff
}
}
}
Is there a way to store all of the control events in a custom class like below?
No, the event handlers themselves must be defined in the code-behind of the same view class where the element is defined and the handler is hooked up.
You could move the code inside the event handlers to another class though:
public partial class MainWindow : Window
{
private YourClass _handler = new YourObject();
public class ControlEvents : MainWindow //Custom class
{
private void Abutton_Click(object sender, RoutedEventArgs e)
{
_handler.HandleButtonClick(e);
}
}
}
But you should look into MVVM: https://msdn.microsoft.com/en-us/library/hh848246.aspx. There is a reason why this is the recommended design pattern for developing XAML based UI applications.
If you don't use mvvm:
You can create user control for area of controls and load this user control in your main window.
Also - you can take your code of "do stuff" to another class and call it from the event function.
for example:
functions.cs
dostuff1()
{
...
}
dostuff2()
{
...
}
your usercontrol/mainwindow.xaml.cs:
functions f = new functions();
private void Abutton_Click(object sender, RoutedEventArgs e)
{
f.dostuff1();
}
good luck
You can move all the events to Partial class in separated file.
call the file MainWindowEvents.cs or something. (to remember what is it)
Related
So far i separated action with Command Binding. but i need to implent many thing to work same as built-in event. ex, OnClick, OnChange and so on. the MVVM pattern only means is no code behind in ViewModel class. all thing like Component. instead make all thing from scratch. why not just make Event in ViewModel implementation like component. so just attacch and detach that event collection class. is there new way to do this? so far i can think is encapsulate control with event and inhrited to viewmodel class.
public class Utility
{
public static string Manipulation(string search)
{
return search + "Reesult";
}
}
public class CustomWindow : Window
{
protected virtual void SearchBtn(object sender, RoutedEventArgs e)
{
MessageBox.Show( Utility.Manipulation(search.Text) );
}
}
public partial WindowViewModel : CustomWindow
{
public WindowViewModel
{
InitializeComponent();
}
}
<TextBox x:Name="search" />
<Button Click="SearchBtn"> Search </Button>
I am creating Windows form application and its main form contains a panel. Different user controls are being loaded on that panel on button click.
namespace LearnCSharp
{
public partial class MainForm : Form
{
private void configButton_Click(object sender, EventArgs e)
{
var uControllerDashboard = new Controllers.Dashboard();
panel.Controls.Add(uControllerDashboard);
updateNotification("active");
}
private void updateNotification(string state)
{
switch (state)
{
case "active" :
//Do something here
break;
}
}
}
}
when click config button it loads Dashboard user controller into Panel there is a another apply button in Dashboard userControl. When I click that button I need to call updatNotification method in MainForm Class.
namespace LearnCSharp.Controllers
{
public partial class Dashboard : UserControl
{
private void btnApply_Click(object sender, EventArgs e)
{
// Need to call updateNotification method here.
}
}
}
how can I achieve my requirement. I appreciate any help. Thanks.
Use events for that.
Instead of calling the MainForm inside the UserControl, create an event in the UserControl and have the MainForm subscribe that event. Inside the UserControl you just need to trigger the event.
There are many examples on web about this. Just take a look at this:
How do I make an Event in the Usercontrol and Have it Handeled in the Main Form?
How do i raise an event in a usercontrol and catch it in mainpage?
Hope this helps.
newbie question :(
I'm making a program using windows forms and i have a lot of small methods like this
private void label1_Click(object sender, EventArgs e)
{
textBox1.Select();
}
private void label13_Click(object sender, EventArgs e)
{
textBox13.Select();
}
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
plotGraph(prostokat);
}
in the Form1.cs file and to make the code more transparent, I would like to move these small methods out somewhere to an external file (class?) but I don't really know how to do this. If they were normal methods I would just make a class and create an object of that class and just call the methods using that object but these are functions that "happen" when a user action is performed i.e. a textbox is clicked, so I'm not sure how to make this work.
It is possible to create an extra partial class (separated file) for your Form1 and place your cluttering methods there.
Or you could collapse them with #region
#region UI Handlers
#endregion
The perfect solution would be using some kind of MVVM for WinForms. In that case in your ViewModel you can implement your business logic separately from the code-behind.
Check out this:
https://www.codeproject.com/articles/364485/mvvm-model-view-viewmodel-patte
Hope it helps!
Have a look at your Form class subsection. It most cases it is still a partial class. Create a new .cs file in the same subsection in your project and add another partial form class to it.
You can find additional information here:
Partial Classes and Methods
Sure, you can add a new class to your project (right-click the project in Solution Explorer --> Add Class --> ) and put your methods there. Then you will need to hook the methods up to the controls in code:
I added a static class called "Form Methods" and put a method in there for label1 Click event:
static class FormMethods
{
public static void label1_Click(object sender, EventArgs e)
{
Label label = (Label) sender;
// Try to find the textbox through the label's parent form
TextBox textBox = (TextBox) label.Parent.Controls.Find("textBox1", true).First();
if (textBox != null)
{
textBox.Select();
}
}
}
Then in the Form Designer code, you can hook up the event:
this.label1.Click += new System.EventHandler(FormMethods.label1_Click);
Alternatively, you can make the class part of your original form class, and it will still be a separate file. If you want to do this, you can then make your event a private non-static method, and you would change the class definition to a public partial class:
public partial class Form1 // <-- This used to be: static class FormMethods
{
// This used to be: public static void label1_Click
private void label1_Click(object sender, EventArgs e)
{
. . .
And then hooking up the event looks like:
this.label1.Click += new System.EventHandler(label1_Click);
You can create any number of partial class files mimicking your original and group methods inside as your functionally needs - however, you won't be able to use the designer to directly navigate to your callbacks. That is, if you double click a graphic element or click an event of a graphic element you will have an unexpected behavior: in both cases you will have an event handler generated in your first partial and a hook created to that . . . so you can't directly navigate to those handlers anymore, and you need to go trough your partial files looking for their definitions.
Use partial to split C# code like this.
public partial class Employee
{
public void DoWork()
{
}
}
public partial class Employee
{
public void GoToLunch()
{
}
}
I have a main form with 3 User Controls attached to it. How can I have events inside a specific User Control reach out and modify the UI of the other two User Controls without creating spaghetti code?
Main Form (Form1.cs)
public partial class Form1 : Form
{
private UserControl1 userControl11;
private UserControl2 userControl21;
private UserControl3 userControl31;
public Form1()
{
InitializeComponent();
}
}
UserControl1.cs
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// Change buttons around and fill in some data on user control 2 and 3
}
private void button2_Click(object sender, EventArgs e)
{
// Remove certain elements from control2 and 3
}
// .. So forth
}
I will have many events that do many different things on the other two user controls. I am creating a basic interface that's similar to Visual Studio where I can open projects, close them, add files, etc. These actions on one form should load up different windows and such in the other controls. What's the best method to achieve this? Creating custom events and parsing each event in the main form? Or accessing each user control directly from the first one? Or...?
The general pattern for events is:
public class MyClass{
public static EventHanlder<ofSomeType> MyEventHandler;
public void MyClass{
MyEventHandler = _MyEventHandler;
}
public void _MyEventHandler(object sender, OfSomeType args){
//do something with passed in args.
}
}
Other classes would use these eventhandlers like this...
public class myOtherClass{
public void doSomething(){
//do something here and signal the other class
var ofSomeTypeData = GetData();
MyClass.MyEventHandler(ofSomeTypeData);
}
}
Some will argue this style is too closely coupled but it works flawlessly and is a good start.
Create an event inside each UserControl. Form1 should subscribe to events on those controls.
So suppose that UserControl1 allows the user to sort the data. Then you might write this:
public Form1()
{
InitializeComponent();
// I assume UserControl1 was created by this point
userControl1.OnDataSorted = DataSorted;
}
// This will be called when the user wants to sort the data
private void DataSorted(UserControl1 sender, EventArgs e)
{
// Change buttons around and fill in some data on user control 2 and 3
}
Then you will create an event and a delegate in the UserControl.
public class UserControl1 {
public delegate void DataSortedDelegate(UserControl1 sender, EventArgs e);
public event DataSorted OnDataSorted;
private void button1_Click(object sender, EventArgs e)
{
if (OnDataSorted != null)
OnDataSorted(this, EventArgs.Empty);
// Replace EventArgs.Empty above with whatever data Form1 needs
}
This approach creates a separation of concerns between Usercontrol1 and Form1. The control does not need to actually modify the private controls inside Form1. It merely notifies Form1 that something has happened, and allows Form1 to make the changes.
I have my form1(Design) with a button in it, but in my form1(Class) it's getting pretty crowded so I want to make a new class. But how do I make the button work in the new class(the new classes name is form2(Class). Of course the function works for the button in form1(Class) so how do I make it work from form2(Class)?
Create your own custom UserControl with own Controls and logic. Or create partial class for your From1 and put events logic there.
It would be worth considering separating your UI code (e.g. button event handling) from the core logic of your application.
There are many way of doing this but the common place to start is with a model class that represents the data and/or logic your window is manipulating.
Try searching on "Windows forms mvc" or "windows forms mvp".
MVP : http://msdn.microsoft.com/en-us/magazine/cc188690.aspx
MVC : Implementing MVC with Windows Forms
What you should really do is use the Model/View/Controller or Model/View/Presenter pattern.
Essentially what you do is to make the Form class (which is the View class) pretty dumb. It doesn't know what to do when various events (such as button presses) occur. Instead, it raises events to indicate what has happened.
Then you write a Controller class which is responsible for creating the View and attaching to its events. The Controller knows what to do when a button is pressed, and responds accordingly (perhaps by calling methods or setting properties in the View class).
The Model is just an abstraction of the data used by the Controller to populate the View class.
Ideally, the View knows nothing about the Model. The Controller is the entity that is responsible for sitting between the Model and the View.
This approach lets you split the business logic out from the form, which simplifies things and makes it much easier to change things and also to unit test.
I posted an example about this a while ago here: https://stackoverflow.com/a/15605436/106159
You should try to disentangle the UI logic from the "business logic", moving it out of the event and in a new class.
e.g. if now you have:
// in Form1.cs
private void btn_Click(object sender, System.EventArgs e) {
OpenDatabaseConnection();
string customerName=SearchCustomerByCode(someTextBox.Text);
someOtherTextBox.Text=customerName;
CloseDatabaseConnection();
}
you should have something like this instead:
// in Form1.cs
private void btn_Click(object sender, System.EventArgs e)
{
string customerCode=someTextBox.Text;
var cs = new CustomerRepository();
string customerName=cs.SearchCustomerByCode(customerCode);
someOtherTextBox.Text=customerName;
}
// in CustomerRepository.cs
//... logic to get the data from the DB, no specific knowledge of form1
public class CustomerRepository.cs
{
public string SearchCustomerByCode(string customerCode)
{
//...
}
}
You could do something like this, which would work, but not very well.
Form 1
public partial class Form1 : Form
{
Form2 f2 = new Form2();
public Form1()
{
InitializeComponent();
}
public void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("Test");
f2.ShowDialog();
}
}
Form 2
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form1 f1 = new Form1();
f1.button1_Click(null, null);
}
}