Adding control at runtime, not following panels padding properties - c#

I am adding controls at run-time to my Panel, but the are not following the panels Padding property.
The Label below, just gets placed in the very top left of my panel. I have my panel at 20,20,20,20 in Padding, but it's still not working. Any ideas? Thanks!
//Thickness Combo Clicked\\
private void Thickness_Clicked(object sender, EventArgs e)
{
RadMenuItem item = sender as RadMenuItem;
switch (item.Text)
{
case "6":
RadLabel label = new RadLabel();
label.Text = "Test";
radPanel1.Controls.Add(label);
break;
case "20":
//
break;
}
}

Padding of Panel is just respected by those child controls which you have set their Dock property to a value different from None. In fact, as mentioned in documentations
The Padding property of Panel is a more general realization of the DockPadding property of a ScrollableControl and the property property determines the border inside of this control for docked components.
So in above case which you added the Label without setting Dock property, the label and panel controls are working properly and your label will be shown at 0,0 location.
To solve the problem you need to set the Location manually or use a TableLayoutPanel instead.

Related

How to change the BackColor of Buttons inside a TableLayoutPanel?

Is there any way to change the background color of Buttons inside a TableLayoutPanel?
The background color of the Buttons will be changed with a click of a Button outside of the TableLayoutPanel.
Actually I wanted to know how to identify Buttons which are inside a TableLayoutPanel.
I am providing a code block below. Please correct me.
private void button10_Click(object sender, EventArgs e)
{
Button btnClicked = sender as Button;
// wanted to convert the controls of tablelayoutpanel
if (tableLayoutPanel1.Controls is Button)
{
btnClicked = (Button)tableLayoutPanel1.Controls;
}
else
continue;
}
// Couldn't call the buttons inside the tablelayoutpanel.
Control.Controls is a collection. It cannot be cast to a single object. This:
tableLayoutPanel1.Controls is Button
will be notified in the code editor (green underline) with the message:
The given expression is never of the provided ('Button') type.
This cast will instead generate an error:
btnClicked = (Button)tableLayoutPanel1.Controls;
CS0030: Cannot convert type
'System.Windows.Forms.TableLayoutControlCollection' to
'System.Windows.Forms.Button'
To modify a property of all Button controls child of a TableLayoutPanel (or any other container), you can enumerate its Controls collection, considering only the child Controls of a specific Type.
For example, change to Color.Red the BackColor property of all Buttons inside a TableLayoutPanel:
foreach (Button button in tableLayoutPanel1.Controls.OfType<Button>()) {
button.BackColor = Color.Red;
}
Change to Text property of all Buttons in the first Row:
Note that, here, I'm using a generic Control type instead of Button. This is because the Text property is common to all controls that derive from Control. The Text property is defined in the Control class.
foreach (Control ctl in tableLayoutPanel1.Controls.OfType<Button>())
{
if (tlp1.GetRow(ctl) == 0)
ctl.Text = "New Text";
}
Modify a property of a Control in the first Row, first Column of the TableLayoutPanel:
Here, I don't know what kind of control is located at coordinates (0, 0), but I know it's an object derived from the Control class. So I can set a property that belongs to this class and is threfore inherited.
It may happen that a specific property is not relevant for a control Type. In this case nothing will happen (you can try to set the Text property of your TableLayoutPanel).
(tableLayoutPanel1.GetControlFromPosition(0, 0) as Control).BackColor = Color.Green;

UserControl inside Panel inside UserControl not working

I am having some trouble creating the template of my application :
I am making some dynamic parts of forms and I use a panel in which I include my User Control according to the choice of the user. The panel has the same size as the user control but it doesn't work at runtime. The panel in which the UC is included is inside another UC also.
I tried autoSize = true, fixed size and many things but I don't know why it goes like this. Any idea?
Some parts of my code to load the User Control :
UC_panel.Controls.Clear();
UC_ADDRESS uca = new UC_ADDRESS();
uca.Dock = DockStyle.Fill;
uca.AutoSize = true;
UC_panel.Controls.Add(uca);
My UserControl for the address
At runtime it goes bigger
Since you set
uca.Dock = DockStyle.Fill;
and also
uca.AutoSize = true;
(which is redundant)
it is possible that some other container has its AutoScaleMode set to Font and its font size is bigger.

Center Checkboxes in Table Layout Panel

I'm trying to center my checkboxes in a TableLayoutPanel, but they always end up looking left-aligned due to the nature of the checkbox control. See picture below:
I want each rows checks to be left-aligned, but for it to appear more centered. Something like the following:
I've checked around online, and I can center the checkboxes by setting AnchorStyles.None which is not what I want, because then the checkboxes are not aligned. I have them set to Dock.Fill so you can click anywhere in the cell to activate the checkbox.
I'm currently just padding my table to achieve a similar effect, but it's by far not an acceptable solution long-term. Also, padding the cells will line break the checkbox text without taking up all the available space on the row (since some of the row is being eaten by padding). The same goes for using a spacer-cell on the left of the table, not an ideal solution.
Does anyone have any ideas? Thanks!
This may work for you:
Set all the ColumnStyles of your TableLayoutPanel as .SizeType = SizeType.AutoSize.
Set your TableLayoutPanel.AutoSize = true and TableLayoutPanel.AutoSizeMode = AutoSizeMode.GrowAndShrink;
Add this code to center your checkboxes (as well as your TableLayoutPanel) dynamically:
//SizeChanged event handler of your tableLayoutPanel1
private void tableLayoutPanel1_SizeChanged(object sender, EventArgs e){
//We just care about the horizontal position
tableLayoutPanel1.Left = (tableLayoutPanel1.Parent.Width - tableLayoutPanel1.Width)/2;
//you can adjust the vertical position if you need.
}
UPDATE
As for your added question, I think we have to change some things:
Set your CheckBox AutoSize to false. The solution before requires it to be true.
Add more code (beside the code above):
int checkWidth = CheckBoxRenderer.GetGlyphSize(yourCheckBox.CreateGraphics(),System.Windows.Forms.VisualStyles.CheckBoxState.MixedNormal).Width;
//TextChanged event handler of your CheckBoxes (used for all the checkBoxes)
private void checkBoxes_TextChanged(object sender, EventArgs e){
UpdateCheckBoxSize((CheckBox)sender);
}
//method to update the size of CheckBox, the size is changed when the CheckBox's Font is bolded and AutoSize = true.
//However we set AutoSize = false and we have to make the CheckBox wide enough
//to contain the bold version of its Text.
private void UpdateCheckBoxSize(CheckBox c){
c.Width = TextRenderer.MeasureText(c.Text, new Font(c.Font, FontStyle.Bold)).Width + 2 * checkWidth;
}
//initially, you have to call UpdateCheckBoxSize
//this code can be placed in the form constructor
foreach(CheckBox c in tableLayoutPanel1.Controls.OfType<CheckBox>())
UpdateCheckBoxSize(c);
//add this to make your CheckBoxes centered even when the form containing tableLayoutPanel1 resizes
//This can also be placed in the form constructor
tableLayoutPanel1.Parent.SizeChanged += (s,e) => {
tableLayoutPanel1.Left = (tableLayoutPanel1.Parent.Width - tableLayoutPanel1.Width)/2;
};
Instead of having the checkboxes in cells, having each one inside a panel all inside a groupbox will allow the checkboxes to fill each panel and have a click able area around them. then with the groupbox dock set to fill and the panels' anchors set to top,bottom they all stay centered.

Cannont Update control in WPF custom control

I have created a custom control which holds a button in it. The button is styled, so as to hold a grid with two rows, an image in the first and a TextBlock in the second. I have written an Event Handler for the custom control. When the mouse enters the path of the object the MouseEnter event fires, where I try to change the TextBlock's FontSize and Foreground color, however the control does not update. In contrast, I have tried to modify an regular TextBlock's(not part a custom control and controltemplate) properties, and they update correctly, on the fly.
What am I missing here?? Here is the code for the event handler:
private void ThemeButton_MouseEnter(object sender, MouseEventArgs e)
{
InitializeProperties();
TextElement.FontSize = 16;
TextElement.Text = "new text";
TextElement.Foreground = Brushes.Red;
TextBlock element = MainWindow.FindChild<TextBlock>(MainWindow.StartWindow, "textField");
element.Text = "new text for regular textblock";
element.Foreground = Brushes.Red;
}
InitializeProperties is a methid that initializes TextElement(typeof TextBlock) and ImageElement(typeof Image) properties. They are not null. The properties are just regular .NET properties.
wow...my problem actually was that the Properties(TextElement and ImageElemenet) were pointing to the elements in the template(custom control) and not to the elements that actually got rendered in the Window...
Remember, when searching for elements, always start your search after rendering is complete(i.e. start search when a user action fires an event or something similar) so that the elements get into the Visual Tree!!

c# .NET - Tabpage margin

I have a tabcontrol with 3 tabpages. I need to add a left margin to the first tabpage ( so move all tabpages move right of 200px ). How can I do it??
Using Visual Studio 2008 / c#
EDIT Reading again I think you're more looking for the controls on each page to be on the right of the tabs rather than moving the buttons.
As Hans suggests a panel would be the easiest way. But it's not pretty.
private void Form1_Load(object sender, EventArgs e)
{
// Create spacer tab with a name long enough to reach the 200px mark
TabPage spacer = new TabPage("..............................................................");
tabControl1.TabPages.Insert(0, spacer);
// Create a panel at the same location of the tab control.
Panel spacerBlock = new Panel();
spacerBlock.Name = "spacer";
spacerBlock.Location = tabControl1.Location;
spacerBlock.Width = 198;
spacerBlock.Height = 20;
this.Controls.Add(spacerBlock);
spacerBlock.BringToFront();
}
private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
{
// Ensure the user can't use the keyboard to somehow select the spacer tab.
if (tabControl1.SelectedIndex == 0)
tabControl1.SelectedIndex = 1;
// Check if the second (first I guess) tab is selected and adjust the panel to keep the look consistant.
if (tabControl1.SelectedIndex == 1)
this.Controls["spacer"].Width = 198;
else
this.Controls["spacer"].Width = 200;
}
You'll want to make sure the tab isn't selectable by the user via keyboard shortcuts thus the index change check.
Also note the panel will have to have its width adjusted if the second (first in your case) tab is selected due to the 3d GUI effect.
Honestly the hassle of taking into account the appearance settings of the end user to ensure the spacer tab's text and the panel width are correct length doesn't really make up for fancy look IMHO.
Only other option I could think of would be a tab panel with a 16px height. Again this would have to be adjusted depending on the end users appearance settings, not to mention the excess overhead in getting it all working.
If it's the AjaxControlToolkit tab control, add this CSS class:
.TabContainer .ajax__tab_header
{
padding-left: 200px;
}
you would need a work-around for that because tab pages can't be moved. You might wanna place a groupbox inside the tabpage and then you can add all the controls inside the groupbox as you desire...
// tabPage 1
this.tabPage1.Controls.Add(this.groupBox1);
// groupBox1
this.groupBox1.Location = new System.Drawing.Point(200,6);
this.groupBox1.Controls.Add(this.textBox1);
this.groupBox1.Controls.Add(this.AnyControls); //etc

Categories