How can I add buttons dynamically to a WPF application? - c#

I am new to WPF and i want to create a window which will create a variable number of buttons with an image.
List<Button> HeroButtons = new List<Button>();
for (int i=0;i<20;i++)
HeroButtons.Add(new Button(){});
foreach( Button but in HeroButtons)
{
var brush = new ImageBrush();
brush.ImageSource = new BitmapImage(new Uri("Resources/lina.png", UriKind.Relative));
but.Background = brush;
}
Nothing appears if I run the application.

Give your grid or other container a name, then use that name (ie Grid1) to add children.
foreach (Button but in HeroButtons)
{
Grid1.Children.Add(but);
}

Related

C# : how to modify properties of dynamically created controls like panels etc

I need help with modifying the properties of a dynamically created controls.
First I created 2 panels on the form dynamically like this:
public void create_panels()
{
Panel panel1 = new Panel();
panel1.BackColor = Color.Red;
panel1.Location = new Point(0, 0);
panel1.Size = new Size(320, 480);
this.Controls.Add(panel1);
Panel panel2 = new Panel();
panel2.BackColor = Color.Red;
panel2.Location = new Point(320, 0);
panel2.Size = new Size(320, 480);
this.Controls.Add(panel2);
}
The problem I can't seam to find any clear information about how to modify them after they where (dynamically) created. One would thinks that simply doing something like this below would be easy and nice: (to change the panels color and position). However, this obviously doesn't work since the panel was created dynamically:
panel1.BackColor = Color.Blue;
panel1.Location = new Point(320, 0);
Can someone please help post the simplest way to modify properties of dynamically made control (panel or textbox) changing the controls location or color after it has been created in a dynamic method?
If you still have a reference to the control, you can of course just set the properties directly, as in the following example. The trick is to save the reference as a form-scope variable (instead of as a local variable).
class SomeForm : Form
{
protected Panel _panel1;
public Form_Load(object sender, EventArgs e)
{
_panel1 = new Panel
{
BackColor = Color.Red,
Location = new Point(0, 0),
Size = new Size(320, 480)
};
this.Controls.Add(panel1);
}
public void Example()
{
_panel1.BackColor = Color.Blue; //Simple to change it if you have a reference already
}
}
If you don't want to keep a reference, you can also grab one from the Controls collection, like this:
class SomeForm : Form
{
public Form_Load(object sender, EventArgs e)
{
Panel panel1 = new Panel
{
Name = "SomeNameICanUse", //Important!
BackColor = Color.Red,
Location = new Point(0, 0),
Size = new Size(320, 480)
};
this.Controls.Add(panel1);
}
public void Example()
{
var panel1 = this.Controls.Find("SomeNameICanUse") as Panel; //use the name to find it
if (panel1 != null) panel1.BackColor = Color.Blue;
}
}

Add controls dynamically from another class C#

I have a panel called mainPanel in my Form1 and I want to add controls to it from another class. I tried to set the visibility to public but it didn't work.
This is where I create my controls:
public List<Control> addControlsToMain(string SearchWord, Size ContainerSize)
{
List<Control> ListOfControls = new List<Control>();
Panel Box;
Label Title, Content;
int PositionCounter = 10;
foreach (string data in GetSearchData(SearchWord))
{
Box = new Panel();
Title = new Label();
Content = new Label();
Box.Size = new Size((int)(ContainerSize.Width * 0.8), 100);
Title.Size = new Size(Box.Width, 20);
Content.Size = new Size((int)(Box.Width * 0.8), 60);
Box.Location = new Point(10, PositionCounter);
Title.Location = new Point(25, 10);
Content.Location = new Point(25, 40);
Title.Text = "Title";
Content.Text = "Content here";
ListOfControls.Add(Box);
Box.Controls.Add(Title);
Box.Controls.Add(Content);
PositionCounter += 110;
}
return ListOfControls;
}
Where GetSearchData(SearchWord) is just another function that returns random strings in a list, this function addControlsToMain() belongs to my class SearchFunctions.cs (a class separated from the Form1). I've tried to add these controls doing this:
var mainForm = new Form1();
SearchFunctions src = new SearchFunctions();
System.Drawing.Size panelSize = mainForm.mainPanel.Size;
foreach(System.Windows.Forms.Control data in src.addControlsToMain("Stack overflow", panelSize))
{
mainForm.mainPanel.Controls.Add(data);
}
My class CommandFunctions.cs is who has to add these controls. How can I add these list of controls to my panel?
You could go about this a few ways. One of which would be to add a SearchFunctions object as a a property to your Form1 class. Then use that object to call the method that adds the controls.
public partial class Form1 : Form
{
SearchFunctions src = new SearchFunctions();
public void Button_Click(object sender, EventArgs e)
{
List<Control> myControls = src.addControlsToMain(mySearchWord, mySize);
foreach (Control c in myControls)
{
this.Controls.Add(c);
}
}
}
This example uses a button click but you would place that method anywhere you want.
The problem is most likely here:
var mainForm = new Form1();
You're creating a new instance of Form1 that never gets displayed.
Here are some options:
Pass a reference to your existing Form1 instance into your class and add the controls using that reference.
or
Use the addControlsToMain() function directly from the Form itself so you can add the controls using this as Juken has demonstrated in his post.
or
Pass the controls out to the form using a custom event.
I have rather used webform, but still, this should work: I am basically trying to add controls
To a ** Panel** (instead of Form)in one class(say Main.cs) And
Create and add the controls to this Panel from another class(say class1.cs)
========================================================================
Steps:
1.Make use of the appropriate namespaces for calling control class utility
ex: System.Web.UI.Web Controls (in my case)
2.In Main.cs
Panel Panel1= new Panel();
foreach(some condition)
{
class1.addControlsToMain("xyz_Searchword", 2, ref Panel1); //Calls the method which creates the controls
}
Class1.cs
{
Public static void addControlsToMain(string searchword, int size,ref Panel p1)
{
List<WebControl> list = new List<WebControl>(); //should be List<Control> for Windows
Label lb1, title;
lb1 = new Label();
title = new Label();
lb1.Text = "Test Label Control1";
title.Text = "Test Title Label Control";
p1.Controls.Add(lb1);
p1.Controls.Add(title);
list.Add(p1);
}
}
To cut the long story short, try using Ref keyword. Hope this helps in a bit.

How to define an event to a .cs class that is returning a collection of labels?

I have a method that is returning a collection of Labels although i am able to set an properties of label but i want to define the paint event of label so that i can draw the items there in some format.
public List<Label> drawLabel()
{
lstLable = new List<Label>();
foreach (cOrderItem item in currOrder.OrderItems)
{
_lbl = new Label();
_lbl.Width = 200;// (int)CanvasWidth;
_lbl.BackColor = Color.AliceBlue;
_lbl.Text = item.ProductInfo.ProductDesc;
_lbl.Height = 20;
_lbl.Dock = DockStyle.Top;
_lbl.Paint()////this is the event i want to define for drawign purpose.
lstLable.Add(_lbl);
}
return lstLable;
}
I am returning this collection to a form where i am taking each label and adding to a panel.
It's not quite clear if you mean winforms, wpf or webforms, but in winforms just use the Control.Paint-event as any other event:
public List<Label> drawLabel()
{
lstLable = new List<Label>();
foreach (cOrderItem item in currOrder.OrderItems)
{
_lbl = new Label();
_lbl.Width = 200;// (int)CanvasWidth;
_lbl.BackColor = Color.AliceBlue;
_lbl.Text = item.ProductInfo.ProductDesc;
_lbl.Height = 20;
_lbl.Dock = DockStyle.Top;
//this is the event i want to define for drawign purpose.
_lbl.Paint += new PaintEventHandler(LblOnPaint);
lstLable.Add(_lbl);
}
return lstLable;
}
// The Paint event method
private void LblOnPaint(object sender, PaintEventArgs e)
{
// Example code:
var label = (Label)sender;
// Create a local version of the graphics object for the label.
Graphics g = e.Graphics;
// Draw a string on the label.
g.DrawString(label.Text, new Font("Arial", 10), Brushes.Blue, new Point(1, 1));
}
You can subscribe to the paint event of Label class
_lbl.Paint+=yourCustomPaintMethod;
use ObservableCollection instead of List
You can also learn to use Reactive Extensions.
I would subclass the Label control and override the OnPaint Method.

Using a border to move a textbox

I'm making a C# project with WPF and Visual Studio.
I'm stuck at trying to drag/move a TextBox around on my canvas in run-time.
I got the idea that, if you make a border thickness big enough, you could use the border for some sort of focus and then make an EventHandler for the border?
private Canvas DrawBox(ClassBox box)
{
Canvas myCV = new Canvas();
TextBox box1 = new TextBox();
box1.Background = new SolidColorBrush(Colors.Blue);
box1.BorderThickness = new System.Windows.Thickness(5);
box1.Foreground = new SolidColorBrush(Colors.White);
box1.MinWidth = 30;
box1.TextWrapping = TextWrapping.Wrap;
box1.AcceptsReturn = true;
myCV.Children.Add(box1);
Canvas.SetLeft(box1, box.Left);
Canvas.SetRight(box1, box.Right);
Canvas.SetTop(box1, box.Top);
return myCV;
}

C# with WPF Call UserControl form from Window Form

Actually, I'm using C# with WPF. Let me explain again:
I have create UserControl (WPF) with one Button (Click on Button to create Image and textBox (Like New Folder)).
And I have another Window form (WPF) with Button and I want to Click on Button in Window Form to do Action instead of Button in UserControl. Here is the code of UserControl:
private void btnNewRoom_Click(object sender, RoutedEventArgs e)
{
Image img = new Image();
img.VerticalAlignment = System.Windows.VerticalAlignment.Top;
img.Width = 100;
img.Height = 100;
var assemblyLocation = Assembly.GetExecutingAssembly().Location;
var applicationDirectory = System.IO.Path.GetDirectoryName(assemblyLocation);
img.Source = new BitmapImage(new Uri("/Resources/Images/folder.png", UriKind.RelativeOrAbsolute));
StackPanel sp = new StackPanel();
TextBox tb = new TextBox();
tb.Width = 120;
tb.Height = 25;
tb.Text = "New Folder";
sp.Children.Add(img);
sp.Children.Add(tb);
AddNewRoom.Children.Add(sp);
}
and It is possible ?
Note: Any good way to Click button to Create Image and TextBox?
Implement a static event handler in your WPF control, and simply call it from your Window Form's button click event.

Categories