I have a problem with 2 Windows Forms which I created in c#. The first form (menu) has a PrintPreviewDialog object. The "menu" form then instantiates a copy of the send class "file" and call a ShopDialog method.
The "file" class write a file and calls a method (direct) in the "menu" class.
The problem I have is that the "direct" method is not known to the "menu" class. I think the answer is to define a copy of "menu" class in the "file", but I can't see have to do that.
Thanks for any help in advance.
John
namespace CSharp
{
public partial class MainMenu : Form
{
// Fields for printing.
public PrintDocument printDocument1 = new PrintDocument();
PageSettings printPageSettings = new PageSettings();
static RichTextBox printRichTextBox = new RichTextBox();
static string stringToPrint = "";
Font printFont = new Font("Arial", 10);
/****************************************************
* Select the Data->File-IO menu item. *
****************************************************/
private void fileIoToolStripMenuItem1_Click(object sender, EventArgs e)
{
File_IO fileIoDialog = new File_IO();
fileIoDialog.ShowDialog();
}
/****************************************************
* Initiate the printing process. The data to be *
* printed will be read from a file and stored in a*
* rich text box. The print menu buttons are *
* enabled. *
****************************************************/
public static void PrintInitialise(String printSource)
{
try
{
// Read text file and load into printRichTextBox.
FileStream printStream = new FileStream(printSource, FileMode.Open, FileAccess.Read);
printRichTextBox.LoadFile(printSource, RichTextBoxStreamType.PlainText);
printStream.Close();
// Initialise string to print.
stringToPrint = printRichTextBox.Text;
}
catch (Exception ex)
{
// Display error message if they appear.
MessageBox.Show(ex.Message);
}
}
/****************************************************
* Select the Data->File-IO menu item. *
****************************************************/
public void PrintDirect()
{
printDocument1.Print();
}
/****************************************************
* Select the Data->File-IO menu item. *
****************************************************/
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
int numChars;
int numLines;
string stringForPage;
StringFormat strFormat = new StringFormat();
// Based on page setup, define drawable rectangle on page
}
}
}
namespace `enter code here`CSharp
{
public partial class File_IO : Form
{
MainMenu mainBransom;
public File_IO()
{
InitializeComponent();
}
private void btnPrint_Click(object sender, EventArgs e)
{
MainMenu.PrintInitialise(printSource);
mainBransom.PrintDirect();
}
You could use a property to store a reference to the menu class in the send class.
public class send: Form
{
public send(Form menuForm)
{
menu = menuForm;
}
public Form menu { get; private set; }
//... some other methods and properties
public void SomeButton_Click(object sender, EventArgs e)
{
// you have access to the direct method (provided it is public)
menu.direct();
}
}
In order to instantiate the send class you need to pass a reference to the menu form.
Related
I am currently using EasyTabs for C#, and it's working fine but I need to be able to at least change the title of the tab from my application, and I can't seem to find anything that will let me do that so far. I'm talking about changing the tab name not the entire form name just the tab names at the top of the screen.
so I need to be able to take a variable from Form1 and change the tab name, again not all the tabs, but specific tabs that get opened, depending on the page, the variable will be different and each tab needs to be named respectively, just as it would if you were going to different sites in different tabs in chrome.
I have looked at all possible stack overflow questions that already exist and none have really helped, so any help on this would be greatly appreciated, and at this point, I would be happy with even only have tab names and not being able to change the favicon, but both would be amazing.
AppContainer.cs
using System;
using EasyTabs;
public partial class AppContainer : TitleBarTabs
{
public AppContainer()
{
InitializeComponent();
AeroPeekEnabled = true;
TabRenderer = new ChromeTabRenderer(this);
Icon = Properties.Resources.icon;
Text = "Example";
}
public override TitleBarTab CreateTab()
{
return new TitleBarTab(this)
{
Content = new Form1
{
Text = "New Tab"
}
};
}
private void AppContainer_Load(object sender, EventArgs e)
{
}
}
Form1.cs
using EasyTabs;
using System.Windows.Forms;
public partial class Form1 : Form
{
protected TitleBarTabs ParentTabs
{
get
{
return (ParentForm as TitleBarTabs);
}
}
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
Program.cs
using System.Windows.Forms;
using EasyTabs;
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
AppContainer container = new AppContainer();
container.Tabs.Add(
new TitleBarTab(container)
{
Content = new Form1
{
Text = "New Tab"
}
}
);
container.SelectedTabIndex = 0;
TitleBarTabsApplicationContext applicationContext = new TitleBarTabsApplicationContext();
applicationContext.Start(container);
Application.Run(applicationContext);
}
}
I've seen the answer before on github a while back, you can change the tab name using ParentTabs.SelectedTab.Caption = e.Title;
I'm not entirely sure where "ParentTabs" was supposed to be located though, if you figure it out please update us
Edit; Sorry for the vague answer. In order to have the ParentTabs variable, you need this code:
protected TitleBarTabs ParentTabs
{
get
{
return (ParentForm as TitleBarTabs);
}
}
You will also need to invoke a new action and Redraw the tabs, using ParentTabs.RedrawTabs();
if you wish to show a favecon and have a title show then use the following
Favecon Code:
private void WebUI_AddressChanged(object sender, AddressChangedEventArgs e)
{
_ = this.Invoke(new MethodInvoker(() =>
{
URLSearch.Text = e.Address;
{
Uri url = new Uri("https://" + new Uri(WebUI.Address).Host + "/favicon.ico");
try
{
Icon img = new Icon(new System.IO.MemoryStream(new
WebClient().DownloadData(url)));
this.Icon = img;
}
catch (Exception)
{
this.Icon = Properties.Resources.tempIcon;
//change tempIcon to your desired icon, extension is .ico
}
}
}));
}
and this is for your Title Code:
private void WebUI_TitleChanged(object sender, TitleChangedEventArgs e)
{
this.Invoke((Action)delegate
{
FindForm().Text = e.Title;
});
}
and for all of this to work then you need to use the AddressChanged and TitleChanged Event in your main form like so
WebUI.AddressChanged += WebUI_AddressChanged;
WebUI.TitleChanged += WebUI_TitleChanged;
and that should wrap things up, i hope this helped you.
I am making an application that loads a separate form, the user puts in information, and then when done, it will show up on the primary form the application loaded with first.
The issue is that I tried multiple solutions to get this to load in, but it will not load in after the information is put in. I have tried this.Controls.Add(Label); which is what I have seen the most, but it has not worked. Another way I tried was doing Label.Show();, but the same result, with nothing showing. The AddContacts(string Name) method below is how I add the contact
The AddContact_Click(object sender, EventArgs e) method is a button that, when pressed, opens another form that allows information to be inserted.
public partial class Phonebook : Form
{
public Phonebook()
{
InitializeComponent();
MaximumSize = new Size(633, 306);
}
private void AddContact_Click(object sender, EventArgs e)
{
MakeContact MC = new MakeContact();
MC.Show();
}
public void AddContacts(string Name)
{
Label name = new Label();
//Added Style and Location of Label...
name.Text = Name;
name.Location = new Point(98, 13);
name.Font = new Font("Microsoft Sans Serif", 13, FontStyle.Bold);
this.Controls.Add(name);
Refresh();
}
}
Below is the Method I used when the Finish button is pressed, for when the user is done with the information, and then the AddContacts() method is called
public partial class MakeContact : Form
{
public MakeContact()
{
InitializeComponent();
MaximumSize = new Size(394, 377);
}
private void FinishContact_Click(object sender, EventArgs e)
{
//FullName is the name of the TextField when asking for a name
string Name = FullName.Text;
Phonebook PB = new Phonebook();
PB.AddContacts(Name);
//Closes Separate Form and goes back to the
Close();
}
}
Expectation:
It should load the label into the form after the information is put in.
Actual:
It will not show what so ever.
EDIT: Added More to the Code and to the Question since I didn't do too good of asking the question, sorry about that :/
An example of what I described in the comments:
When you do this:
Phonebook PB = new Phonebook();
you create a new instance of the PhoneBook class (your form): this is not the same Form instance (the same object) that created the MakeContact Form and the one you're trying to update. It's a different object.
Whatever change you make to this new object, it will not be reflected in the original, existing, one.
How to solve:
Add a Constructor to the MakeContact Form that a accepts an argument of type PhoneBook and a private object of type Phonebook:
private PhoneBook pBook = null;
public MakeContact() : this(null) { }
public MakeContact(PhoneBook phoneBook)
{
InitializeComponent();
this.pBook = phoneBook;
}
Assign the argument passed in the constructor to the private field of the same type. This Field will then used to call Public methods of the PhoneBook class (a Form is a class, similar in behaviour to other class).
It's not the only possible method. You can see other examples here.
Full sample code:
public partial class Phonebook : Form
{
private void AddContact_Click(object sender, EventArgs e)
{
MakeContact MC = new MakeContact(this);
MC.Show();
}
public void AddContacts(string Name)
{
Label name = new Label();
// (...)
this.Controls.Add(name);
}
}
public partial class MakeContact : Form
{
private PhoneBook pBook = null;
public MakeContact() : this(null) { }
public MakeContact(PhoneBook phoneBook)
{
InitializeComponent();
this.pBook = phoneBook;
}
private void FinishContact_Click(object sender, EventArgs e)
{
string Name = FullName.Text;
this.pBook?.AddContacts(Name);
this.Close();
}
}
I try to developp an app for users to create a lot of computer's configuration, with OS / Language / etc ...
When he validate a configuration, I would like the choices to be stored in a custom attribute button
private void VALIDATE_Click(object sender, EventArgs e)
{
string Computer = Text_Computer.Text;
if (myList.Any(str => str.Contains(Computer)))
{
MessageBox.Show(Computer+"Already Exist");
}
else
{
Button button = new Button();
button.Size = new System.Drawing.Size(195, 30);
button.Tag = Computer;
button.Name = Computer;
button.Text = Computer;
button.CustomOS = comboBox_OS.SelectedItem;
button.CustomLanguage = comboBox_Language.SelectedItem;
flowLayoutPanel3.Controls.Add(button);
myList.Add(Computer);
MessageBox.Show(Computer + "added");
}
In my GUI, if Users want to edit a configuration, he click on the new button representing the configuration and all choices are back, like :
comboBox_OS.SelectedItem = button.CustomOS;
comboBox_Language.SelectedItem = button.CustomLanguage;
Is that possible to create my custom attribute like button.CustomOS and button.CustomLanguage ?
Regards
It is possible and quite easy. You just derive a new class from the original Button and declare two new Properties. I included the code into a simple example.
using System;
using System.Windows.Forms;
namespace StackOverflow
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
}
private void cbOS_SelectedIndexChanged(object sender, EventArgs e)
{
//Save selection.
ComboBox cb = (ComboBox)(sender);
btn1.CustomOS = cb.SelectedItem.ToString();
}
private void btnSelect_Click(object sender, EventArgs e)
{
//Restore selection on click.
MyButton btn = (MyButton)(sender);
cbOS.SelectedItem = btn.CustomOS;
}
//Declare a new class deriving from the original Button.
public class MyButton : Button
{
public String CustomOS { get; set; }
public String CustomLanguage { get; set; }
}
}
}
Program suppose to draw shapes on panel1.
This is code for my main form:
namespace DrawShapes
{
public partial class Form1 : Form
{
List<Shape> myShapeList;
Shape shape;
public Form1()
{
InitializeComponent();
}
public void AddShape(Shape myshape)
{
myShapeList.Add(shape);
}
public List<Shape> MyShapeList
{
get { return myShapeList; }
}
private void Form1_Load(object sender, EventArgs e)
{
myShapeList = new List<Shape>();
shape = new Shape();
}
private void drawMeButton_Click(object sender, EventArgs e)
{
EditShape editShape = new EditShape();
editShape.Shape = shape;
if (editShape.ShowDialog() == DialogResult.OK)
{
this.shape = editShape.Shape;
myShapeList.Add(shape);
panel1.Invalidate();
}
editShape.Dispose();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
int panelWidth = panel1.ClientRectangle.Width;
int panelHeight = panel1.ClientRectangle.Height;
Pen penLine = new Pen(Color.Blue, 1);
Graphics g = e.Graphics;
if (myShapeList != null)
{
foreach (Shape element in myShapeList)
{
label1.Text = element.Width.ToString();
g.DrawRectangle(penLine, element.XCordinates, element.XCordinates, 50, 50);
}
}
}
}
}
and here is code for my edit shape dialog box
namespace DrawShapes
{
public partial class EditShape : Form
{
Shape shape = null;
public EditShape()
{
InitializeComponent();
}
public Shape Shape
{
get { return shape; }
set { shape = value; }
}
private void button1_Click(object sender, EventArgs e)
{
shape.Width = 50;
shape.Height = 50;
shape.XCordinates = int.Parse(textBox1.Text);
shape.YCordinates = int.Parse(textBox2.Text);
shape.Type = 0;
DialogResult = DialogResult.OK;
}
}
}
I am having problem assigning shape object(from Edit Shape form) to myShapeList, all properties are set to 0 for some reason. Please help.
Perhaps the problem is your AddShape method. You seem to be adding shape each time instead of the shape that's getting passed into the method (myshape).
What happens if you do this instead?
public void AddShape(Shape myshape)
{
myShapeList.Add(myshape); // myshapeinstead of shape
}
It seems that you're not actually adding your shape to your shapelist. You're taking in myShape and then trying to add in shape. This should come up as an intellisense error.
public void AddShape(Shape myshape)
{
myShapeList.Add(shape);
}
EDIT: Nevermind, it wouldn't come up as an error because you have a member variable named shape. You're getting zero for everything because it's calling the default constructor for shape.
The big problem is in your call to the edit form. You are adding to the list the same object reference. So when you modify the reference inside the edit form you change all the elements added to the list to the inputs set in the latest call
Change your code to
private void drawMeButton_Click(object sender, EventArgs e)
{
using(EditShape editShape = new EditShape())
{
// Here, create a new instance of a Shape and edit it....
editShape.Shape = new Shape();
if (editShape.ShowDialog() == DialogResult.OK)
{
// Add the new instance to the list, not the same instance
// declared globally. (and, at this point, useless)
myShapeList.Add(editShape.Shape);
panel1.Invalidate();
}
// The using blocks makes this call superflous
// editShape.Dispose();
}
}
Then it is not clear when you call the method AddShape(Shape myshape) but it is clear that you have typo in that method
I have found my mistake.I Created new event handler with wrong parameters. Therefore information that suppose to be passed by my dialog OK button was never correctly assigned. Silly mistake. Thanks guys.
I've got code and i know I'm 99% of the way there. C# coding in MS VS2008.
Basically I have a form that has 4 radio buttons and a Continue button. the user clicks one of the radio buttons and clicks continue, and this all works fine.
However, I want to use the value entered by the user (i.e. if they click the first button, I want a variable equal to 1, 2nd button equals 2 and so on). I tried doing this in various points but the only place I can get it to run is in the private void btnOkClick line, which means I can use the values outside this void, which is what I really want.
I've tried playing around with setting some enums and such (commented out in the code below), but I can't quite get it. I know I must be close but my novice-ness is truly showing as I keep reading posts and can't quite grasp it.
In short, I want to be able to have other classes in my VS2008 project be able to reference whatever value the user selected in the initial form.
namespace AmortClient
{
public partial class frmLoadACTFCST : Form
{
public frmLoadACTFCST()
{
InitializeComponent();
//set the parent of the form to the container
//this.MdiParent = parent;
}
//public enum ACTFCST
//{
// ACT = 1,
// FCST = 2,
// PLAN = 3,
// FiveYearPlan2012=4
//}
//private ACTFCST _actfcst = ACTFCST.ACT;
//public ACTFCST actfcst
//{
// get { return _actfcst; }
// set { _actfcst = value; }
//}
private void frmLoadACTFCST_Load(object sender, EventArgs e)
{
}
private void groupBox1_Enter(object sender, EventArgs e)
{
}
private void btnActual_CheckedChanged(object sender, EventArgs e)
{
}
private void btnForecast_CheckedChanged(object sender, EventArgs e)
{
}
private void btnPlan_CheckedChanged(object sender, EventArgs e)
{
}
private void btn5YrPlan2012_CheckedChanged(object sender, EventArgs e)
{
}
private void btnContinue_Click(object sender, EventArgs e)
{
string ACTFCSTtext = "";
int dataTypeKey = 0;
if (btnActual.Checked)
{
ACTFCSTtext = btnActual.Text;
dataTypeKey = 1;
}
else if (btnForecast.Checked)
{
ACTFCSTtext = btnForecast.Text;
dataTypeKey = 2;
}
else if (btnPlan.Checked)
{
ACTFCSTtext = btnPlan.Text;
dataTypeKey = 3;
}
else if (btn5YrPlan2012.Checked)
{
ACTFCSTtext = btn5YrPlan2012.Text;
dataTypeKey = 4;
}
string msg = "";
msg = ACTFCSTtext + " " + dataTypeKey;
//btn5YrPlan2012
MessageBox.Show(msg);
Close();
}
}
}
Your dataTypeKey and ACTFCSTtext variables need to be declared as instance variables for your Form object if you want to access them from any other methods within your form. If you want to use them with some other form, you can pass them either as constructor arguments, or set some properties of said other form.
So you'd declare them just after the class declaration if you want them to be instance variables. They should still be private, meaning they can only be accessed from within your frmLoadACTFCST class.
public partial class frmLoadACTFCST : Form
{
private string ACTFCSTtext = "";
private int dataTypeKey = 0;
...
EDIT: if you want to access variables from one object in a different object (or static class), your options are as follows...
1) Declare your variables as public instance variables (same as shown above but public; these are known as Properties when you give them getter and setter methods). Your class that needs access to these variables would need to have a reference to the class that owns the variables.
Example:
FormA has a public property named SomeString.
FormB needs to access SomeString.
FormB needs a reference to FormA, and would access the variable as...
formAReference.SomeString
2) Pass the values of the variables as arguments to some method for the class that needs access.
Example:
FormA has a private instance variable named SomeString.
FormB needs access to SomeString.
If FormA instantiates FormB, it can pass the value of SomeString to FormB's constructor...
//From within FormA's code
FormB formB = new FormB(SomeString);
//FormB's constructor
public FormB(string someString)
{
this.someString = someString;
}
Maybe there is a smarter way to do it.
public partial class frmLoadACTFCST : Form
{
public frmLoadACTFCST()
{
InitializeComponent();
actfcst = ACTFCST.ACT;
btnActual.Tag = ACTFCST.ACT;
btnActual.Checked = true;
btnForecast.Tag = ACTFCST.FCST;
btnPlan.Tag = ACTFSCT.PLAN;
btn5YrPlan2012.Tag = ACTFCST.FiveYearPlan2012;
}
public enum ACTFCST
{
ACT = 1,
FCST = 2,
PLAN = 3,
FiveYearPlan2012=4
}
public static ACTFCST actfcst { get; private set; }
private void CheckedChanged(object sender, EventArgs e)
{
// All the buttons uses this Click-event.
actfcst = (sender as Button).Tag as ACTFCST;
}
private void btnContinue_Click(object sender, EventArgs e)
{
MessageBox.Show(actfcst.ToString());
Close();
}
}
The point is that all the buttons calls CheckedChanged when clicked.
Using a static means that others can access the value using something like this:
frmLoadACTFCST.ACTFCST value = frmLoadACTFCST.actfcst;
// Do something based on value.
I hope this helps you in yoyr quest.
If you select a control in design view, the properties window contains an item named "Modifiers". You can make the control public here.
A better way would be to create a new public property on your form that yields the value of the currently selected radio button.