I have a project in which when the user clicks the button and a label becomes visible and I have 20 labels and I want to make it display labels randomly on each click
You would first need to get all labels. This is the easiest using LINQ:
var labels = Controls.OfType<Label>().ToArray();
And then randomly make on of them visible:
var random = new Random();
var label = labels[random.Next(0, labels.Count - 1)];
label.Visible = true;
Related
I'm new working with C# and I'm asking on here because I didn't find a solution searching in google and other questions on SO, I will explain what my example application does:
When I run it it display a form with a textbox by default, this textbox always will be shown, after type some text and press enter it will generate a new textbox and a new button (all the controls even the default textbox are inside a panel), and the new textboxes have the same functionality as the default textbox, when I click on the button generated next to its textbox it removes the button itself and the textbox but after that if I remove some random textboxes it leaves a space between these controls, how can reorganize this content to dont let space between them?
As you can see in the image, can you tell me how can fix this or give me an advice to achieve this? thank you, by the way this is the method I use to generate the buttons and textboxes
private void GenerarTextBox()
{
panelContenedor.VerticalScroll.Value = panelContenedor.VerticalScroll.Minimum;
TextBox tb = new TextBox();
tb.Text = "Prueba " + id;
tb.Name = "txtBox" + id;
tb.KeyDown += new KeyEventHandler(TextBox_Keydown);
Button bt = new Button();
bt.Cursor = Cursors.Hand;
bt.Text = "X";
bt.Name = "btnPrueba" + id;
bt.Click += new EventHandler(ClickBotones);
Point p = new Point(20, 30 * id);
Point pb = new Point(130, 30 * id);
tb.Location = p;
bt.Location = pb;
panelContenedor.Controls.Add(tb);
panelContenedor.Controls.Add(bt);
tb.Focus();
id++;
}
And this to remove the textboxes and the buttons
private void ClickBotones(object sender, EventArgs e)
{
Button bt = sender as Button;
string nombreBoton = bt.Name;
string idBoton = nombreBoton.Substring(9);
string nombreTextBox = "txtBox" + idBoton;
foreach (Control item in panelContenedor.Controls.OfType<Control>())
{
if (item.Name == nombreTextBox)
{
panelContenedor.Controls.Remove(item);
panelContenedor.Controls.Remove(bt);
}
}
}
You could place your dynamic controls on a FlowLayoutPanel. Either directly or grouped together in a Panel or UserControl.
Set the FlowDirection property of the FlowLayoutPanel to TopDown. The FlowLayoutPanel will then arrange your controls automatically. You can also set the WrapContents property to False and AutoScroll to true to make the scroll bar appear.
Alternatively you can use FlowDirection = LeftToRight, place the text box and the button directly on the FlowLayoutPanel and let the child controls wrap (WrapContents = True). In the child controls, a new property FlowBreak appears. It can be set to True for the last control to appear in a row and let the next one wrap independently of the width of the FlowLayoutPanel.
You can also play with the Margin property of the child controls to control their layout in the FlowLayoutPanel as the Location property becomes useless.
The FlowLayoutPanel (as well as the Panel) is available in the Toolbox in the section "Containers".
When you delete the controls, you need to do a recalc of the positions. So when you have added them in sequence, you can go with:
bool repos = false;
Point p;
foreach (Control item in panelContenedor.Controls.OfType<Control>())
{
if (repos)
{
Point tmp = item.Location;
item.Location = p;
p = tmp;
}
if (item.Name == nombreTextBox)
{
panelContenedor.Controls.Remove(item);
panelContenedor.Controls.Remove(bt);
repos = true;
p = item.Location;
}
}
I need to measure the DesiredSize or ActualHeight/Width of a button (and radio button) without actually putting it onto the visual tree but I keep getting back non-sense values. This same approach works when measuring other controls such as TextBlock.
var button = new Button
{
Content = "Hello World",
FontSize = 15
};
button.Measure(new Size(maxWidth, double.PositiveInfinity));
var height = button.DesiredSize.Height;
var width = button.DesiredSize.Width
I'm getting back 21px for height and 0px for width. Any idea why I'm getting 0 back for width?
I need to measure the DesiredSize or ActualHeight/Width of a button (and radio button) without actually putting it onto the visual tree but I keep getting back non-sense values.
If you assign a string value to Button.Content, the value will be assigned to the inside TextBlock through Binding in runtime, which happens after the Button.Measure (You can see this by adding the button to the page and check the LiveProperty Explorer):
So you get the wrong desired size.
As a workaround, you can create a TextBlock and assign this TextBlock to the button:
var tbContent = new TextBlock()
{
Text = "Hello World",
FontSize=15
};
var button = new Button
{
Content = tbContent,
};
var h= button.DesiredSize.Height;
button.Measure(new Size(200, double.PositiveInfinity));
var height = button.DesiredSize.Height;
var width = button.DesiredSize.Width;
Then you will get the correct Size of this button.
I'm guessing that this isn't possible. You're measuring the button before it has loaded its template.
I can only suggest doing something like this:
var but = new Button();
but.Content = "Hello";
var popup = new Popup();
popup.Child = but;
popup.IsOpen = true;
popup.Visibility = Visibility.Collapsed;
but.Loaded += (s, e) =>
{
System.Diagnostics.Debug.WriteLine(but.RenderSize);
popup.IsOpen = false;
};
But it's kind of hacky, and the button won't load until some later time, making this whole process asynchronous which might be difficult to manage.
I'm trying to build a form application in Visual Studio 2010 using C#.
The program will be reading a excel file that contains a list of filenames, and will dynamically generate textbox for each filename.
Below is my code, just for clarification. I wanted to make the label a link to the file, that's why I didn't use checkboxes[i].Text = filename
CheckBox[] checkboxes = new CheckBox[fileCount];
Label[] labels = new Label[fileCount];
for (int i = 0; i < fileCount; i++ )
{
//creating a checkbox
checkboxes[i] = new CheckBox();
checkboxes[i].Location = new Point(360, (145 + i * 30));
checkboxes[i].Name = String.Format("checkbox{0}", i.ToString());
this.Controls.Add(checkboxes[i]);
//creating filename label
labels[i] = new Label();
labels[i].Location = new Point(20, (150 + i * 30));
labels[i].Text = existingFiles[i];
labels[i].Width = 330;
this.Controls.Add(labels[i]);
}
Say if fileCount equals to 100, it will make the form really big/long and won't be able to fit properly on most monitors.
Is there a way to make all dynamically generated checkboxes and labels all grouped in a area and just have the user be able to scroll? Something like a panel with scrolling? I don't know if there's anything like that.
I thought about using CheckedListBox, but doing that way I won't be able to make the filename a link. I want the user be able to click on the label and the file will be opened automatically, instead of selecting it.
Any help is appreciated!
Most controls have the AutoScroll property. Set this to true, and the control will automatically add a scrollbar when necessary. You can use the Panel control and add all of your links/checkboxes to that (if you don't want your whole form to scroll).
I have several pictureboxes added in FlowLayutPanel, There is and index which have a number of picture box im lookin at, i can change this index by buttons.
How can i configure my FlowLayoutPanel.VerticalScroll that i could look only at the picture box with name of my index, and i couldnt look at another picture boxes.
I suggest that i have to change FlowLayoutPanel.VerticalScroll.Minimum and Maximum, but i can`t, if i change minimum - it countinue to be 0. here is a code:
flowLayoutPanel1.Dock = DockStyle.Fill;
flowLayoutPanel1.FlowDirection = FlowDirection.TopDown;
flowLayoutPanel1.Controls.Add(pictureBox3);
flowLayoutPanel1.Controls.Add(pictureBox2);
flowLayoutPanel1.Controls.Add(pictureBox1);
flowLayoutPanel1.Controls.Add(pictureBox4);
flowLayoutPanel1.AutoScroll = true;
flowLayoutPanel1.WrapContents = false;
MessageBox.Show( flowLayoutPanel1.VerticalScroll.Maximum.ToString());
this.flowLayoutPanel1.VerticalScroll.Minimum = 300;
MessageBox.Show(flowLayoutPanel1.VerticalScroll.Minimum.ToString());
flowLayoutPanel1.PerformLayout();
How can i do that?
I am new at C# & XAML development. I created a metro app with several textboxes. These textboxes are loaded in XAML data through a StackPanel in C# code, it has to be hardcoded. The problem is, I have no clue how I can add some empty spaces between every single textbox. Has anyone an idea?
The Code :
private void AddLastestCreatedField()
{
// Load the last created Field From DB
DBFunction.FieldTypes latestField;
DBFunction.Class1 myDBClass = new DBFunction.Class1();
latestField = myDBClass.GetLastestField();
// add new textbox and put it on the screen
var dragTranslation = new TranslateTransform();
//Generate the TextBox
TextBox fieldTextBox = new TextBox();
fieldTextBox.Name = "fieldTextBox_" + latestField.ID.ToString();
fieldTextBox.FontSize = 15;
fieldTextBox.Background.Opacity = 0.8;
ToolTip toolTip = new ToolTip();
toolTip.Content = latestField.Description;
ToolTipService.SetToolTip(fieldTextBox, toolTip);
fieldTextBox.IsReadOnly = true;
// Add Drag and Drop Handler for TextBox
fieldTextBox.ManipulationMode = ManipulationModes.All;
fieldTextBox.ManipulationDelta += fieldTextBox_ManipulationDelta;
fieldTextBox.ManipulationCompleted += fieldTextBox_ManipulationCompleted;
fieldTextBox.RenderTransform = dragTranslation;
dragTranslationDict.Add(fieldTextBox.Name, dragTranslation);
fieldTextBox.RenderTransform = dragTranslation;
// Add TextBox to a List to control later
TxtBoxList.Add(fieldTextBox);
// Generate TextBlock for each TextBlock
TextBlock fieldTextBlock = new TextBlock();
// fieldTextBlock.Name = "fieldTextBlock_" + cnt.ToString();
fieldTextBlock.TextAlignment = TextAlignment.Right;
fieldTextBlock.HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Right;
fieldTextBlock.Name = "fieldTextBlock_" + latestField.ID.ToString();
fieldTextBlock.Text = latestField.Name;
fieldTextBlock.FontSize = 15;
fieldTextBlock.Height = 33;
// Add Drag and Drop Handler for TextBlock
var dragTranslation2 = new TranslateTransform();
fieldTextBlock.RenderTransform = dragTranslation2;
dragTranslationDict2.Add(fieldTextBlock.Name, dragTranslation2);
// Add TextBlock to a list to control later
TxtBlockList.Add(fieldTextBlock);
TextBoxStack.Children.Add(fieldTextBox);
TextBlockStack.Children.Add(fieldTextBlock);
}
I'll skip the usual "What have you tried?" question and say you probably can get what you need by setting the Margin property on the TextBox - the Margin property will add "space" around the control size as a sort of padding (not to be confused with the Padding property, which will add space inside the control extents)
I don't know what you are really up to, but either use the Margin-property of the textbox. It defines, how much space there will be around the control,
See MSDN for more information.