I am using C# Wpf and i would like to create a function that once you click on a button A new Textbox will appear is this possible and I want to know if it possible to increase the form hight when a new Textbox is created
The question isnt exactly specific but yes you can make new UI elements in the code-behind. In WPF you would put your button on the window, then add the "Click" event to it. Then in the click event you could code something like. . .
private void Button_Click(object sender, RoutedEventArgs e)
{
Button newButton = new Button(); //Create a new button control and assign it to newButton
newButton.Width = 35; //Access fields like this (You can access any of the ones you access from the Xaml user interface)
newButton.Height = 20;
newButton.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
newButton.VerticalAlignment = System.Windows.VerticalAlignment.Top;
newButton.Content = "click me!";
grMain.Children.Add(newButton); //Add it to the grid
}
grMain is the name of my grid, make sure you name it and call it by the name. You can also call other elements, such as a stack panel or whatever you need. So for your case just make it a textbox instead of a button
Oops didnt see the second part of your question! To resize the window you need to first add a name to it in the XAML (Like you would name a grid or button - just name the window something). And just as we called grMain in my example call that and change the height/width properties.
Related
I am trying to resize my TreeView window during runtime and I cant do it.
in my program I can press on a button and the TreeView opens as a popup window.
The TreeView is inside a Control:
private Control parent;
mytree= new TreeView();
parent.Controls.Add(mytree);
I have already tried to search for any resize properties but no luck, I can't find a way that the tree will be resizable during runtime.
The only way I can see it is to delete the control and to put it in a Form and then I can make it look like the same but I still want to know if there is another way to solve this, please if someone knows !
thank you
Assign anchor property to tree view so it resizes with form (or maybe control he is child of)
Here is example of anchoring button:
// Add a button to a form and set some of its common properties.
private void AddMyButton()
{
// Create a button and add it to the form.
Button button1 = new Button();
// Anchor the button to the bottom right corner of the form
button1.Anchor = (AnchorStyles.Bottom | AnchorStyles.Right);
// Assign a background image.
button1.BackgroundImage = imageList1.Images[0];
// Specify the layout style of the background image. Tile is the default.
button1.BackgroundImageLayout = ImageLayout.Center;
// Make the button the same size as the image.
button1.Size = button1.BackgroundImage.Size;
// Set the button's TabIndex and TabStop properties.
button1.TabIndex = 1;
button1.TabStop = true;
// Add a delegate to handle the Click event.
button1.Click += new System.EventHandler(this.button1_Click);
// Add the button to the form.
this.Controls.Add(button1);
}
Important part is button1.Anchor where in example button is anchored to bottom right of window, so it will just follow window as you resize, but you can anchor to all sides of window and it will resize with it.
Try different things and you will figure it out.
SOURCE: MSDN
I have a usercontrol that is loaded to a panel on Form1 in a winform application when a menu option is selected. The usercontrol has buttons that are used to fire the printer select dialog and allow the user to setup multiple printers for the application. Each button configures the settings property in the application to store a printer. Under each button there is a label that displays the name of the printer from the settings property.
I am using events to manage the button clicks from the usercontrol. Everything works great with the events storing the correct printer in the settings property. However, I want the label to display the selected printer immediately after I select it in the printer dialog. It won't display the change of printer until I navigate away from the usercontrol and back. Then it shows the correct printer name for each button.
I am able to write to the label text just fine. I've tried refreshing the label, invalidating and updating the label. Nothing seems to work. Only navigating away and back will display the printer names in the labels.
Here is one of my button click handlers on Form1:
private void btnTwoByHalf_Click(object sender, EventArgs e)
{
ucPrinterSetup prn = new ucPrinterSetup();
twoByHalf.PropName = "TwoByHalfPrn";
twoByHalf.SetPrinter(twoByHalf.PropName);
prn.lblTwoByHalf.Text = twoByHalf.Printer;
}
Here is my menu option click handler:
private void configurePrintersToolStripMenuItem_Click(object sender, EventArgs e)
{
ClearFrames();
ucPrinterSetup printerSetup = new ucPrinterSetup();
pnlMenu.Controls.Add(printerSetup);
printerSetup.btnTwoByHalfClick += new EventHandler(btnTwoByHalf_Click);
printerSetup.btnFourByOneClick += new EventHandler(btnFourByOne_Click);
printerSetup.btnFourByTwoFiveClick += new EventHandler(btnFourByTwoFive_Click);
printerSetup.btnMiscClick += new EventHandler(btnMisc_Click);
printerSetup.btnDefaultClick += new EventHandler(btnDefault_Click);
printerSetup.btnSecondaryClick += new EventHandler(btnSecondary_Click);
ucConfigurePrinters configurePrinters = new ucConfigurePrinters();
pnlFrame.Controls.Add(configurePrinters);
}
Here is my button click handler from ucPrinterSetup.cs:
private void btnTwoByHalf_Click(object sender, EventArgs e)
{
if (btnTwoByHalfClick != null)
btnTwoByHalfClick(sender, e);
}
Everything else works fine. It just doesn't update the label.text after I select the new printer until I navigate away from ucPrinterSetup and back.
Update 1:
My printers are being stored in the application settings through:
twoByHalf.PropName = "TwoByHalfPrn";
twoByHalf.SetPrinter(twoByHalf.PropName);
twoByHalf.PropName is the name that I've pre-entered in the settings property for the application.
I then set the label text to the name of the printer with:
prn.lblTwoByHalf.Text = twoByHalf.Printer;
In Application-Settings I have preset printer names as:
TwoByHalfPrn - string - User - (no value)
The main problem seems to be that you set the label on a control other than the one you are showing.
When your click event (btnTwoByHalf_Click) is called, you should use
the user control that is currently showing, but instead you create a new one with ucPrinterSetup prn = new ucPrinterSetup();
This is not the same control that is showing, but a completely new control, so when you change the label in prn you change the label in an invisible control, the original control remains unchanged.
I can see 4 ways of getting the original control:
1.
You can get it from the menu. If you only have one instance of this control type in you menu, you can use something like (no error handling in my code):
ucPrinterSetup prn = pnlMenu.Controls.OfType<ucPrinterSetup>().First();
twoByHalf.PropName = "TwoByHalfPrn";
twoByHalf.SetPrinter(twoByHalf.PropName);
prn.lblTwoByHalf.Text = twoByHalf.Printer;
Or, if you do have more than one you can assign different names to your controls and use something like pnlMenu.Controls.Find("YourControlNameGoesHere", false).First();
2.
You can get it from the sender property in your event. The sender is the button in the control, so assuming the button is sitting directly in the control, the button's parent will be the control:
ucPrinterSetup prn = (ucPrinterSetup)((Control)sender).Parent);
If the button is not sitting directly in the control (for example, it might sit in a panel that sits in a control) then you might need to up the chain more, you can put a breakpoint in the event entry and inspect the sender.
3.
The third way is maybe the best, but it requires you to change your design. It seems that you create the control again and again each time the menu is clicked. Maybe there's a good reason for it, but assuming there's no real reason for it, it's probably better to create the user control once when you start, and just switch the original control in and out. Then you can just put your control in a class variable and use it from your event.
4.
And for completeness you can also use a lambda/anonymous method for your event and capture the control when you register the event.
If you do that, then in the method which you register the event, replace the registration code to something like this:
printerSetup.btnTwoByHalfClick += (sender, e) => btnTwoByHalf_Click(printerSetup );
And then change your event method signature and code to be like this:
private void btnTwoByHalf_Click(ucPrinterSetup prn)
{
twoByHalf.PropName = "TwoByHalfPrn";
twoByHalf.SetPrinter(twoByHalf.PropName);
prn.lblTwoByHalf.Text = twoByHalf.Printer;
}
This might be the easiest code and less error prone to use, though notice that if you need to unregister the event later on, it might prove tricky.
Add Buttons:
Button button = new Button();
this.Controls.Add(button);
button.Name = "btn" + id;
button.Text = "AAAA";
The result is the name of a button as btn55, but, how to change text on button name btn55?
something like
private void btnaktual_Click(object sender, EventArgs e)
{
btn55.Text = "BBB";
}
Gives me error:
Error 1 The name 'btn55' does not exist in the current context
Use this.Controls.Find("btn55",true).FirstOrDefault().Text = "BBB";
If you used the designer to put the button in the form, then a member variable would be created with the same name as the name of the form. As you create the button using code, there is no btn55 variable.
When you create the button you have a reference to it. You should just keep that reference so that you can use it later. Make a member variable in the form where you can store it, i.e. declare Button button; (or perhaps a more descriptive name) in the form class instead of inside the method where you create the button. Then you can use the variable later to access the button.
Your entire problem lies in the page load. When you click the button event the page posts back, so if you're control is not reloaded it no longer exists when the click event is called. Either you are not creating the button on postback or the button isn't in viewstate. Find Control will always return null until the button is created so most of these answers won't work for you yet.
These pages will help you:
http://forums.asp.net/t/1186195.aspx?FAQ+Why+do+dynamic+controls+disappear+on+postback+and+not+raise+events+
Dynamically Created Controls losing data after postback
http://www.codeproject.com/Articles/35360/ViewState-in-Dynamic-Control
Once you get that control reloaded, then you can get it from there pretty easily.
Try this:
var btn = Controls.Find("btn55") as Button;
btn.Text = BBB;
You need to search for the button in it's parent controller. Let's say you have a main form and the button placed in it. You can find using id of control in parent.
(MainForm.Controls.Find("btn"+number") as Button).Text= "BBB";
My app needs to be able to dynamically create new form elements and work with them. Right now I have a panel with buttons and labels in it. I need to be able to make a duplicate of this and show it in my app and then work with it.
For example, I have panel1. Inside are label1, button1, and button2.
Label 1 just counts up by seconds.
When you click button1, label1 starts counting up. When you click button2, the timer stops.
My problem is that I need to be able to duplicate panel1 many times and still have the new buttons correspond to the correct labels.
On button_click
private void button1_Click(object sender, EventArgs e)
{
Button theSender = (Button)sender;
Panel parentPanel = (Panel)theSender.Parent;
}
From here, I can't target any of the child control . I'm used to targeting and handles in jQuery, so I don't even know the correct C# terminology for how to explain myself.
If understand your problem correctly, I recommend you to make a Usercontrol with a Panel and fill it with your Label, Button and whatever. Write the events for your buttons in the usercontrol. Then introduce this usercontrol in your form and it should work. You can introduce any number of usercontrols in your form and each button will behave/work for the label in that usercontrol only.
As you mentioned you are new in winforms and you are not sure what I am saying, let me know and I will help if I get enough time.
Hope it helps.
Children of a control can be accessed using Control.Contrtols collection, e.g. to access button on a form:
Button btn = this.Controls["button1"];
But that is only true if button1 is placed directly on your form and button1.Name property is set to "button1" (designer does that automattically, if you are creating your controls dynamically, you have to take care of naming your controls yourself.)
You can also enumerate child controls of any control, e.g. child controls of panel1:
foreach(Control c in panel1.Controls)
{
// do something, e.g.
if(c is Label){//do sth...}
if(c.Name.Equals("label1") && c is Label)
{
Label l = c as Label;
}
}
and as #rapsalands said, UserControl may be an answer for you.
I would create a user control (UserControl) for this.
Check this article for more explanation about the difference between Control and UserControl.
Controls and UserControls are easy to duplicate and the full functionality is there.
You can create new UI Controls in code as you would any other object: Button b = new Button();
Then you can add them to the form using form.Controls.Add(b). You'll need to position and size the controls as well (there are properties available for doing this) and hook up your event handlers using b.Clicked += form.button_click;.
To see an example of this, you can try having a look at the designer.cs file that is generated in Visual Studio (don't make changes to it, just have a look). It will look quite complex at first but might go some way to helping demystify Windows Forms, and you will be able to find all of the properties you need to set in there.
Whenever you update something in the designer, Visual Studio generates new code and puts it in the designer.cs file. The entire form is set up in the InitializeComponent() method, which is called from the constructor of your form. You should be able to copy some of that code and with a couple of modifications use it for creating your own dynamic UI elements.
As rapsalands says, it sounds like a user control would be useful in this situation, as it will help encapsulate the functionality you're after. However that may take a bit of time to get your head round and you may find it simpler for now to do everything in your form without creating a new control.
So you are a beginner and need some time to understand Usercontrol as I mentioned in my previous answer. Use a for loop in the Constructor or Load event of your form to dynamically generate controls.
Panel panel;
Label label;
Button button1;
Button button2;
for(int i = 0; i > count; i++)
{
panel = new Panel();
button1 = new Button();
button2 = new Button();
label = new Label();
panel.Controls.Add(button1);
panel.Controls.Add(button2);
panel.Controls.Add(label);
Controls.Add(panel);
button1.Click += Event1;
button2.Click += Event2;
}
private void Event1()
{
label.Text = "Button 1 Clicked."
}
private void Event2()
{
label.Text = "Button 2 Clicked."
}
This way certainly you can create as many controls you want and will also serve your purpose. Use some variables to locate the panel controls appropriately. Set any properties you wish to add in the for loop for the controls.
This is just an alternative for my previous answer. I still recommend the previous answer given by me. This code is dummy and not tested.
Hope it helps.
I'm programmatically adding ToolStripButton items to a context menu.
That part is easy.
this.tsmiDelete.DropDownItems.Add("The text on the item.");
However, I also need to wire up the events so that when the user clicks the item something actually happens!
How do I do this? The method that handles the click also needs to receive some sort of id or object that relates to the particular ToolStripButton that the user clicked.
Couldn't you just subscribe to the Click event? Something like this:
ToolStripButton btn = new ToolStripButton("The text on the item.");
this.tsmiDelete.DropDownItems.Add(btn);
btn.Click += new EventHandler(OnBtnClicked);
And OnBtnClicked would be declared like this:
private void OnBtnClicked(object sender, EventArgs e)
{
ToolStripButton btn = sender as ToolStripButton;
// handle the button click
}
The sender should be the ToolStripButton, so you can cast it and do whatever you need to do with it.
Thanks for your help with that Andy. My only problem now is that the AutoSize is not working on the ToolStripButtons that I'm adding! They're all too narrow.
It's rather odd because it was working earlier.
Update: There's definitely something wrong with AutoSize for programmatically created ToolStripButtons. However, I found a solution:
Create the ToolStripButton.
Create a label control and set the font properties to match your button.
Set the text of the label to match your button.
Set the label to AutoSize.
Read the width of the label and use that to set the width of the ToolStripButton.
It's hacky, but it works.