I have a WPF Project, Main window contains several grids.
After creating Textboxes and -blocks in a loop I add them to a grid using:
grid1.Children.Add(textbox1);
grid2.Children.Add(textbox2);
...
grid20.Children.Add(textbox20);
Is it somehow possible to replace this piece of code with a loop too?
If you have many of these grid/textboxes it might be wiser to wrap them in another control as Yaho Cho suggested in his comment..
I might be stating the obvious, but if you place the grids and textboxes in a list (i.e. create them in code and add them to the container in code) you can loop them.
List<TextBox> tl = new List<TextBox>(){ ... };
List<Grid> gl = new List<Grid>(){ ... }
for (i=0; i<20; i++)
{
gl[i].Children.Add(tl[i]);
container.Children.Add(gl[i]);
}
Related
I'm currently trying to populate a UniformGrid in WPF.
Some context: I'm trying to build a 2D Sidescroller (I know, WPF is not the best solution to that and I should use Unity or something else. I'd like to try it though). Now, for the map I was thinking about using a UniformGrid and using the children as tiles for my map.
So far, I'm adding empty children to the UniformGrid using this piece of code:
private void CreateMapTiles() {
for (int i = 0; i < 30; i++) {
for (int j = 0; j < 45; j++) {
this.MapGrid.Children.Add(new Image());
}
}
}
Where MapGrid is my UniformGrid.
So, in the end, I want to have 30x45 children.
Now I want to dynamically edit those children in CodeBehind, i.e. make those children an image. Or put another way, I want to update, let's say, the child at index 5 to display another image from my resources, than it did before.
I was thinking about using something like this:
this.MapGrid.Children[1] = new Image() { Source = ReturnSomeSource() };
But for obvious reasons, this doesn't work.
Is there any way i can assign a value to the children during runtime?
I've also played around with this.MapGrid.Children[1].SetCurrentValue() a bit, but neither did I really understand what I was doing, nor did it work in any way.
Does the possibility even exist, to change the UniformGrid children during runtime?
Would a normal Grid do a better job? I wanted to avoid that, because the UniformGrid children are arranged and sized automatically the way i need them without any more effort.
Rather than replacing Imagewith a new Image, change the source on the already existing image.
var tileImage = this.MapGrid.Children[1] as Image;
tileImage.Source = ReturnSomeSource();
I create controls dynamically (checkBoxes, listBox, trackBar...) on a Form, and i put menuStrip using the editor. I'd like to remove all the controls, and i'd like to keep the menu.
When i use this line:
this.Controls.Clear();
it removes the menu as well as the controls, however as i understood, menu items are not controls, they are on the form directly(i can see them if i write "this" and press a dot).
i tried to cycle over the controls and removed only if the type was one of the controls, but some control stayed while some are removed. I cycled using controls.Count. I tried to put the whole cycle to another while() and exit if Controls.Count > 1 like this:
while( this.Controls.Count > 1 )
{
for (int i = 0; i < this.Controls.Count; i++ )
{
if ((this.Controls[i].GetType() != typeof(MenuStrip)) )
{
this.Controls.RemoveAt(i);
}
}
}
It removes the controls and leave the menu alone, but the items that are disappears doesn't disapper in the same time, but some time later, i guess it's becouse the while runs more than one time.
My questions:
1. Why can't it remove all the control at once, while i iterate over the whole thing using controls.count as the upper bound.
2. What's the point of menuStrip as control while toolStripMenuItmes are not control.
This is the classic mistake of modifying the collection that you are iterating. Most collection classes generate an exception when you do that, unfortunately ControlCollection doesn't. It just misbehaves, you'll skip the next control after the one you remove. There's another nasty bug, the Controls.RemoveAt() method doesn't dispose the control you remove, it leaks forever.
Avoid the iteration bug by iterating backwards. And properly dispose, like this:
for (int i = this.Controls.Count-1; i >= 0; i--) {
if (this.Controls[i].GetType() != typeof(MenuStrip)) {
this.Controls[i].Dispose();
}
}
I want to load Form's controls to a panel in C# so the panel will show the same components as the form. I have tried this code:
foreach (Control control in (new Form2()).Controls)
{
panels[panelsCounter].Controls.Add(control);
}
But the problem is that when I'm running the program it loads only the type of control that I've added last (For example if I've been added a label and than I've added a button to the form it shows only a button, but if I add another label, it shows both of the labels, but not the button).
Please help me.
This is a classic bug, you are modifying the collection while you are iterating it. The side-effect is that only ever other control will be moved to the panel. You'll need to do this carefully, iterate the collection backwards to avoid the problem:
var formObj = new Form2(); //???
for (int ix = formObj.Controls.Count-1; ix >= 0; --ix) {
panels[panelsCounter].Controls.Add(formObj.Controls[ix]);
}
Controls are not designed to be displayed multiple times. You cannot add controls to multiple forms, or add the same control to a form multiple times. They simply weren't designed to support it.
You could go through each control and create a new control of the same type, and even copy over the values of their properties (or at least what's publicly accessible to you), effectively cloning them, but it's important that it be a different control that you add to the new panel.
i want to add some UserControls on a LayoutControl via Code. They should appear among each other. And this is the problem. I just become one UserControl to be visible.
I do following at the moment:
foreach (myClass tempMyClass in allObjectsFromMyClass)
{
// I create UserControl
ctrlProgramm programm = new ctrlProgramm();
// I set some label values and so on for Control
programm.BxProgrammInitialiseren(tempMyClass);
// I Add UserControl to the LayoutControl Controls Collection
LayoutControl.Controls.Add(programm);
}
I just can see the Control which is created in the first loop of the foreach.
Maybe they are recline one over the other? Maybe i need to add a Panel first?
Information: The LayoutControl is in Namespace DevExpress.XtraLayout and we are using DevExpress v2010 vol.2
regards
When adding controls into LayoutControl you should wrap these controls with LayoutControlItems as follows:
//Create a layout item and add it to the root group.
LayoutControlItem item1 = layoutControl.Root.AddItem();
item1.Name = "item1";
ctrlProgramm programm = new ctrlProgramm();
// Set the item's Control and caption.
item1.Control = programm;
item1.Text = "Program:";
Related help articles:
How to: Create layout items via code
How to: Create layout groups and items via code
To learn more about the LayoutControl concepts please refer the following articles:
Introducing the XtraLayoutControl
Tutorial: Creating a Simple Layout
I just created a "Usercontrol" in WINFORMS- it just contains 1-Button with some style.
And i need to use the same as array(10) and load it to a form.
Ex:
Dim myButton() As Button = New ucSpecialButton(dataset4Category(i).Tables(0).Rows.Count - 1) {}
Here my usercontrol name is ucSpecialButton
can we create a ONE-Dimensional Array of a WINFORM usercontrol.?
With MAKKAM's words: Yes, you can. I guess you're actually uncertain about whether you can add a dynamic number of controls to a form, because in the designer you cannot define any arrays, you just drag and drop a certain number of controls on the form.
However, in fact Visual Studio simply generates some code in background that adds these controls to a collection. You can just as well write your own code to add an arbitrary number of UserControls to the collection dynamically. Just look at the forms' .designer.cs file to see how it works.
Taking MAKKAM's array controls it could look like this, e.g.:
public MyForm()
{
InitializeComponent(); // this is the call to the auto-generated code
// Here you could add you own code:
foreach (Control control in controls)
{
this.Controls.Add(control); // this is how to add a control to the form.
}
}
Yes, you can.
Control[] controls = new Control[10];
So, what's the problem?
I've just noticed that you edited your question. If I got it right, the only thing you're missing now is (I'm a C# guy, might be that there are some flaws in the following VB.NET code):
for i = 0 to dataset4Category(i).Tables(0).Rows.Count - 1
myButton(i) = New ucSpecialButton();
// ... specific button properties ...
next
For, the code you pasted in your question doesn't create the buttons yet, it only allocates memory for the array:
Dim myButton() As Button = New ucSpecialButton(
dataset4Category(i).Tables(0).Rows.Count - 1) {}
New in this place means to create a new array for the references, not to create new objects. ucSpecialButton(...) in this place is not the constructor for an object. Instead it only denotes the type of object you want to prepare the array for. You can IMHO just as well write New Button(...).
By the way: IMHO it should be
`New ucSpecialButton(dataset4Category(i).Tables(0).Rows.Count)`
Without the - 1. In the for loop however, the - 1 is correct (an array of size 10 goes from 0..9).