I'm Working on a game that uses multiple layouts. To make those layouts, I use user controls by bringing them forward and sending them behind. Now I'm in a phase where I have to send all gathered data (hardness, what type etc) to User control where all rest of the work is done. I'm stuck with sending int values to my user control that does all the work. I thought about sending them with eventhandler, but EventHandler didn't seem to recognize my int values either
In short, I want to pass Int values that I have in a form, to User control
public void liitmine1(object sender, EventArgs e)
{
/*event*/
uCraskus1.BringToFront();
int What = 1;
}
public void kumme(object sender, EventArgs e)
{
uCmehanism1.BringToFront();
int Between = 1;
}
public event EventHandler KummeClick; /*Sends info to mechanism*/
private void KummeNupp(object sender, EventArgs e)
{
if(What == 1) /*The name'what' does not exist in current context error*/
if (this.KummeClick != null)
this.KummeClick(this, e);
}
if (this.KummeClick != null) is just to test, don't mind if anything is wrong with that
You can make your own EventArgs type, like this:
public class KummeClickEventArgs : EventArgs
{
public int MyProperty { get; set; }
}
And then use it (assumption that kumme method is one of the subscribers):
public void kumme(object sender, KummeClickEventArgs e)
{
//here is your logic like:
//int test = e.MyProperty;
uCmehanism1.BringToFront();
int Between = 1;
}
public event EventHandler<KummeClickEventArgs> KummeClick; /*Sends info to mechanism*/
private void KummeNupp(object sender, EventArgs e)
{
if(What == 1) /*The name'what' does not exist in current context error*/
if (this.KummeClick != null)
{
var eventArgs = new KummeClickEventArgs
{
MyProperty = 3
};
this.KummeClick(this, eventArgs);
}
}
Related
I am new to C# and I want to utilize the forms with one another.
I have 2 forms. (1)MMCMLibrary_home and (2)MMCMLibrary_reserve.
In this project, I'm in the stage of changing the label background colors in Form 1 but can't seem to utilize Form 2 to process it.
These are my necessary codes so far:
FORM 1
namespace MMCM_Library
{
public partial class MMCMLibrary_home : Form
{
public static MMCMLibrary_home instance;
//DCR1 Labels
public Label lbl1_1;
public Label lbl1_2;
public Label lbl1_3;
public Label lbl1_4;
public MMCMLibrary_home()
{
InitializeComponent();
instance = this;
lbl1_1 = lblDCR1_9;
lbl1_2 = lblDCR2_11;
lbl1_3 = lblDCR1_1;
lbl1_4 = lblDCR1_3;
public void btnDCR1_Click(object sender, EventArgs e)
{
var reserveDCR1 = new MMCMLibrary_reserve();
reserveDCR1.Show();
}
public void btnDCR2_Click(object sender, EventArgs e)
{
var reserveDCR2 = new MMCMLibrary_reserve();
reserveDCR2.Show();
}
public void btnDCR3_Click(object sender, EventArgs e)
{
var reserveDCR3 = new MMCMLibrary_reserve();
reserveDCR3.Show();
}
public void btnDCR4_Click(object sender, EventArgs e)
{
var reserveDCR4 = new MMCMLibrary_reserve();
reserveDCR4.Show();
}
}
}
FORM 2
when I click any reserve now button in form 1 it will open form 2. However, if I pick a radio button, the background change will always be applied to Discussion Room 1 even I reserved for discussion room 2
namespace MMCM_Library
{
public partial class MMCMLibrary_reserve : Form
{
public static MMCMLibrary_reserve instance;
public MMCMLibrary_reserve()
{
InitializeComponent();
instance = this;
}
private void MMCMLibrary_reserve_Load(object sender, EventArgs e)
{
}
private void splitContainer1_Panel2_Paint(object sender, PaintEventArgs e)
{
}
private void splitContainer1_Panel1_Paint(object sender, PaintEventArgs e)
{
}
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
}
private void radioButton1_CheckedChanged_1(object sender, EventArgs e)
{
}
private void btnDCR1_Click(object sender, EventArgs e)
{
}
public void btnDCRoomsReserve_Click(object sender, EventArgs e)
{
if (rbtn9.Checked)
{
MMCMLibrary_home.instance.lbl1_1.BackColor = System.Drawing.Color.Red;
}
}
}
}
Can you help me to device an efficient way to solve this. Can you also suggest a database method suitable for my beginner project.
You've said that:
the background change will always be applied to Discussion Room 1
Well, yes. It seems you don't pass specific object into Form2. There's strightforward:
MMCMLibrary_home.instance.lbl1_1.BackColor = System.Drawing.Color.Red;
So you'll be always changing backcolor of lbl1_1 of your Form1. What needs to be done is to indicate which room has been selected. You can assign room after you click the button by passing the int parameter:
public void btnDCR1_Click(object sender, EventArgs e)
{
var reserveDCR1 = new MMCMLibrary_reserve(1);
reserveDCR1.Show();
}
or:
public void btnDCR2_Click(object sender, EventArgs e)
{
var reserveDCR2 = new MMCMLibrary_reserve(2);
reserveDCR2.Show();
}
Then, in Form2, at the very top, add something like:
int room; to be able to assign the room number in Form2:
public MMCMLibrary_reserve(int roomNumber)
{
InitializeComponent();
room = roomNumber;
instance = this;
}
And then you could just select room you clicked, by:
public void btnDCRoomsReserve_Click(object sender, EventArgs e)
{
if (rbtn9.Checked)
{
if(room == 1)
{
MMCMLibrary_home.instance.lbl1_1.BackColor = System.Drawing.Color.Red;
}
else if(room == 2)
{
MMCMLibrary_home.instance.lbl1_2.BackColor = System.Drawing.Color.Red;
}
else if(room == 3)
{
MMCMLibrary_home.instance.lbl1_3.BackColor = System.Drawing.Color.Red;
}
else if(room == 4)
{
MMCMLibrary_home.instance.lbl1_4.BackColor = System.Drawing.Color.Red;
}
}
else if(radioButton2.Checked)
{
//etc.
}
else if(radioButton3.Checked)
{
//etc.
}
else if(radioButton4.Checked)
{
//etc.
}
}
I think that was the problem. Try it and let us know.
Is there any way to store the code below in another class called RecordAddControl?
Code from "RecordAdd.cs"
private void txtEilesNum_Enter(object sender, EventArgs e)
{
txtEilesNum.Clear();
txtEilesNum.ForeColor = SystemColors.Desktop;
}
private void txtEilesNum_Leave(object sender, EventArgs e)
{
if (txtEilesNum.Text == "")
{
txtEilesNum.ForeColor = SystemColors.InactiveCaption;
txtEilesNum.Text = "Eil Num";
}
}
Things I've tried like RecordAdd recordAdd = new RecordAdd(); doesn't seem to work when trying to get the class to recognise things like txtEilesNum.
RecordAdd is a form, and txtEilesNum is taken from "RecordAdd.Designer.cs"
it makes more sense to tailor helper class to work with TextBox directly (any TextBox, not only the one in RecordAdd)
public static class TexBoxDecorator
{
public static void UsePlaceholder(this TextBox tb)
{
tb.Enter += tb_Enter;
tb.Leave += tb_Leave;
}
private static void tb_Enter(object sender, EventArgs e)
{
var tb = (TextBox)sender;
tb.Clear();
tb.ForeColor = SystemColors.Desktop;
}
private static void tb_Leave(object sender, EventArgs e)
{
var tb = (TextBox)sender;
if (tb.Text == "")
{
tb.ForeColor = SystemColors.InactiveCaption;
tb.Text = "Eil Num";
}
}
}
txtEilesNum in a known member in RecordAdd, so it can be accessed to add event handlers:
txtEilesNum.UsePlaceholder();
Sure, you can store event handlers in another class, you'll need to make them public, and you'll need to cast the sender to the correct type:
public static class EventHandlers
{
public void EilesNum_Enter(object sender, EventArgs e)
{
var txtEilesNum = (TextBox)sender; // Assumed textbox
txtEilesNum.Clear();
txtEilesNum.ForeColor = SystemColors.Desktop;
}
public void EilesNum_Leave(object sender, EventArgs e)
{
var txtEilesNum = (TextBox)sender; // Also assumed textbox
if(txtEilesNum.Text == "")
{
txtEilesNum.ForeColor = SystemColors.InactiveCaption;
txtEilesNum.Text = "Eil Num";
}
}
}
In your form, you'll still need to wire up the events as before
txtEilesNum.Enter += EventHandlers.EilesNum_Enter;
txtEilesNum.Leave += EventHandlers.EilesNum_Leave;
There are many UserControls in my program. Only one user control (default) is visible without entering a password.
When there is a need to see other Users Controls, then the user must enter the password, and after that, another form should immediately appear (the button on which the call was clicked by the user).
For the model, we have 2 user controls.
The first one opens immediately at startup, and to open the second we have to click on its launch button, then a password entry will appear, and (if the password is correct) the required form will be opened.
In the last code display is my problem.
I have UserLeftPanel that dispalyed always as a left panel and a MainForm(in code Form1).
In LeftUserPanel are many buttons clicked on, Form1 will uploud some UserControl.
I don't understand how to get the method from the base class (Form1) correctly.
Specifically to my program:
And if all the user logic of the calls is wrong, I'll be happy to see the right one.
Every UserControl that displayed by clicked on has this construction
private static UserMainPanel_Saved instanse;
public static UserMainPanel_Saved Instanse
{
get
{
if(instanse==null)
instanse =new UserMainPanel_Saved();
return instanse;
}
}
Code inside UserLeftPanel
public delegate void Handler(object sender,EventArgs e, int control) ;
public event Handler ButtonClick;
protected void ButtonSavedMessages_Click(object sender, EventArgs e)
{
int formnumber = 0;
this?.ButtonClick(this, e,formnumber);// There are ButtonClick Event in Form1
}
Code inside Form1
private void userLeftPanel1_Load(object sender, EventArgs e)
{
userLeftPanel1.ButtonClick += UserControl_ButtonClick;
UserControl_ButtonClick(sender, e, 0);//to display form without password by default
}
public void UserControl_ButtonClick(object sender, EventArgs e,int number)
{
UserControl con=null ;
if (number == 0)
con = UserMainPanel_Saved.Instanse;
else
{
if (UserPassword.Password)
{
if (number == 1)
con = UserMainDaybook.Instanse;
}
else
{
con = UserPassword.Instanse;
}
}
if (!MainPanel.Controls.Contains(con))
{
MainPanel.Controls.Add( con);
con.Dock = DockStyle.Fill;
con.BringToFront();
}
else
{
con.BringToFront();
}
}
Code inside 'UserPassword'
private void button1_Click(object sender, EventArgs e)
{
Password = true;// In this place will be Some Logic
//And my idea is to Invoke there UserControl_ButtonClick( ... ) method, but I don't know how
}
You could try separating the event from the method with the logic (notice two different methods: UserControl_ButtonClick and UserControlClick:
public void UserControl_ButtonClick(object sender, EventArgs e, int number)
{
UserControlClick(number);
}
public void UserControlClick(int number)
{
UserControl con=null ;
if (number == 0)
con = UserMainPanel_Saved.Instanse;
else
{
if (UserPassword.Password)
{
if (number == 1)
con = UserMainDaybook.Instanse;
}
else
{
con = UserPassword.Instanse;
}
}
if (!MainPanel.Controls.Contains(con))
{
MainPanel.Controls.Add( con);
con.Dock = DockStyle.Fill;
con.BringToFront();
}
else
{
con.BringToFront();
}
}```
And then in UserPassword:
private void button1_Click(object sender, EventArgs e)
{
Password = true;// In this place will be Some Logic
Form1.Instance.UserControlClick(0);
//And my idea is to Invoke there UserControl_ButtonClick( ... ) method, but I don't know how
}
This way, you won't need to send object sender, EventArgs e, int number, you can just send the number.
I have two child forms. The first form (Employee) has all the textboxes and a button to open another child form called Search. The Search form has a combobox. After user selects data from combobox then the data from combobox will display in Employee form.
Employee Form:
public string s;
protected override void OnShown(EventArgs e)
{
txtName.Text = s;
base.OnShown(e);
}
Search Form:
private void cbFind_SelectedValueChanged(object sender, EventArgs e)
{
if (cbFind.SelectedItem != null)
{
emp em = new emp();
em.s = cbFind.SelectedItem.ToString();
em.ShowDialog();
}
}
I do not want another Employee form to open after user selects data from combobox. I want it to appear on the Employee Form that is already opened..
EDIT:
Employee Form
namespace Master
{
public partial class Employee : Form
{
public Employee()
{
InitializeComponent();
searchForm.ItemSelected += ItemSelected;
}
private SearchForm searchForm = new SearchForm();
private void ItemSelected(object sender, ItemSelectedEventArgs e)
{
txtName.Text = e.SelectedItem.ToString();
}
private void button1_Click(object sender, EventArgs e)
{
SearchForm searchForm = new SearchForm();
searchForm.Show();
}
}
}
Search Form
namespace Master
{
public partial class SearchForm : Form
{
public SearchForm()
{
InitializeComponent();
}
private void SearchForm_Load(object sender, EventArgs e)
{
}
private void cbFind_SelectedValueChanged(object sender, EventArgs e)
{
if (cbFind.SelectedItem != null)
{
if(ItemSelected != null)
ItemSelected(this, new ItemSelectedEventArgs(cbFind.SelectedItem));
}
}
public delegate void ItemSelectedEventHandler(object sender, ItemSelectedEventArgs e);
public event ItemSelectedEventHandler ItemSelected;
}
public class ItemSelectedEventArgs : EventArgs
{
public object SelectedItem { get; set; }
public ItemSelectedEventArgs(object selectedItem)
{
SelectedItem = selectedItem;
}
}
}
There are many many ways to achieve what you want, the most favorite I like is using some kind of event, yes event is one of the most interesting things in modern programming languages like C# (in .NET environment). However you can choose another solution simply like this:
//in your Search form
public string ShowSearch(){
if(ShowDialog() == DialogResult.OK){
return cbFind.SelectedItem == null ? "" : cbFind.SelectedItem.ToString();
}
return "";
}
//returning "" means some kind of cancel action which will result no search performed.
Search form should be one element in your Employee form, you can show your search form using the method above and get the returned selected item value.
That's not a decent way in some cases, here I introduce you the way using event, you have to declare some event to notify the selecting from user and show the selected item on your Employee form:
//your Employee form
public class Employee : Form {
public Employee(){
InitializeComponent();
searchForm.ItemSelected += ItemSelected;
}
//Search form
private SearchForm searchForm = new SearchForm();
//your ItemSelected handler
private void ItemSelected(object sender, ItemSelectedEventArgs e){
txtName.Text = e.SelectedItem.ToString();
}
}
//your Search form
public class SearchForm : Form {
public SearchForm(){
InitializeComponent();
}
//handler for your combobox SelectedValueChanged event.
private void cbFind_SelectedValueChanged(object sender, EventArgs e)
{
if (cbFind.SelectedItem != null)
{
if(ItemSelected != null) ItemSelected(this, new ItemSelectedEventArgs(cbFind.SelectedItem);
}
}
public delegate void ItemSelectedEventHandler(object sender, ItemSelectedEventArgs e);
//your own event
public event ItemSelectedEventHandler ItemSelected;
}
public class ItemSelectedEventArgs : EventArgs {
public object SelectedItem {get;set;}
public ItemSelectedEventArgs(object selectedItem){
SelectedItem = selectedItem;
}
}
You can use traditional ways which pass values between classes... but I recommend using event (as the code above shows) or at least some kind of delegate. Programming in .NET environment requires you to make familiar with events and delegates much more...
on your parent form you should do this
private void button1_Click(object sender, EventArgs e)
{
Form1 searchForm = new Form1();
if (searchForm.ShowDialog() == DialogResult.OK)
{
string selectedRecord = searchForm.SelectedRecord;
}
}
where button1 is your button to open the search form. Form1 is your search form. and selectedRecord is your property that you set before closing the search form. I have assumed that it is a string though it can be any object.
I am working with a link list. The list is brought up on the form load (size, height, stock, price) displayed in a multiline textbox called textBoxResults. I have three button called First, Next and Last. Naming convention is straightforward, button First click displays first tree, Next, displays each item after first through each button click and Last button shows the last item on list. First works fine but Second only shows the following item after first and gives up, Last displays weird result WindowsFormsApplication1.Form1+Fruit Trees. How can I display the proper tree name according to its position through the button clicks?
Code
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public class ListOfTrees
{
private int size;
public ListOfTrees()
{
size = 0;
}
public int Count
{
get { return size; }
}
public FruitTrees First;
public FruitTrees Last;
}
public void ShowTrees()
{
}
public void Current_Tree()
{
labelSpecificTree.Text = Trees.First.Type.ToString();
}
private void Form1_Load_1(object sender, EventArgs e)
{
}
private void buttonFirst_Click(object sender, EventArgs e)
{
Current_Tree();
}
private void buttonNext_Click(object sender, EventArgs e)
{
Current = Trees.First;
labelSpecificTree.Text = Current.Next.Type.ToString();
}
private void buttonLast_Click(object sender, EventArgs e)
{
Current = Trees.Last;
labelSpecificTree.Text = Trees.Last.ToString();
}
}
}
Several problems in your code (see the comments for corrections):
public int Add(FruitTrees NewItem)
{
FruitTrees Sample = new FruitTrees();
Sample = NewItem;
Sample.Next = First;
First = Sample;
//Last = First.Next;
// Since Add is an operation that prepends to the list - only update
// Last for the first time:
if (Last == null){
Last = First;
}
return size++;
}
Secondly in your Next method:
private void buttonNext_Click(object sender, EventArgs e)
{
// In order to advance you need to take into account the current position
// and not set it to first...
//Current = Trees.First;
Current = Current.Next != null ? Current.Next : Current;
labelSpecificTree.Text = Current.Type.ToString();
}
And in the "last" method:
private void buttonLast_Click(object sender, EventArgs e)
{
Current = Trees.Last;
// show the data, not the name of the Type
labelSpecificTree.Text = Current.Type.ToString();
}
And of course the current method is broken, also...
public void Current_Tree()
{
Current = Trees.First;
labelSpecificTree.Text = Current.Type.ToString();
}