Add control to a panel with autoscroll (c#) - c#

I've a panel with property AutoScroll = true.
By adding other controls dynamically to the panel without scrolling - all works fine!
void addControl(){
int top = 13 + ( this.Controls.Count * cmdSet.Height );
ucCommandSet cmdSet = new ucCommandSet() { Top = top };
this.Controls.Add( cmdSet );
}
But, if the scrollbar is inserted in a different position than TOP [0], the controls are added much further down.
What property do I need to include in the calculation?
regards raiserle
Solution by #LarsTech:
void addControl(){
int top = 13 + ( this.Controls.Count * cmdSet.Height ) + this.AutoScrollPosition.Y;
ucCommandSet cmdSet = new ucCommandSet() { Top = top };
this.Controls.Add( cmdSet );
}

I'm guessing you need to compensate for the scroll position:
{ Top = top + this.AutoScrollPosition.Y };
A FlowLayoutPanel does this for you, by the way.

Related

Custom scrollbar scrolling triggers AutoScroll scrollbars

I've been using a UserControl to display a list of controls. I initially had AutoScroll enabled, and then opted to not using it. I chose against using it as it stood out and simply didn't 'look' good with the controls theme I've been using.
I took a shot at a framework called MetroFramework, and I've opted to use the MetroScrollBar scrollbar control for a vertical scrollbar.
I've fully disabled AutoScroll, and I then decided to implement the Scrollbar. I simply did this by:
scbMain.Scroll += (sender, e) => { VerticalScroll.Value = scbMain.Value; };
(where scbMain is the Scrollbar I'm discussing)
This works, but not as expected. As soon as I scroll, I get a crazy flickering effect from the default scrollbar, as shown here. A longer list has the same effect, but more pronounced.
I've attempted to hide the existing scrollbars:
VerticalScroll.Visible = false;
HorizontalScroll.Visible = false;
VerticalScroll.Enabled = false;
HorizontalScroll.Enabled = false;
This has had no effect on fixing my issue.
It should be noted: My scrollbar is docked to the right and there're no other container controls within the UserControl.
Ok. Problem solved. The issue was in this line of code:
scbMain.Scroll += (sender, e) => { ----> /*(Here*/ VerticalScroll.Value = scbMain.Value; <---- };
You are actully setting the scroll value of your user control, basically you tell the system to invoke the autoscroll property to set the value!
The correct way is to NOT autoscroll the user control but to scroll a container inside eg a panel. So add a panel to your user control. You are going to scroll the panel and all the controls inside it (in this example i will add the button).
this.btnExample.Location = new System.Drawing.Point(62, 0);
this.btnExample.Name = "btnExample";
this.btnExample.Size = new System.Drawing.Size(75, 390);
this.btnExample.TabIndex = 1;
this.btnExample.Text = "Out of Bounds";
this.btnExample.UseVisualStyleBackColor = true;
this.panel1.Controls.Add(this.btnExample);
this.panel1.Location = new System.Drawing.Point(0, 0);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(270, 391); //the width must fit inside your user control and the height was arbitrary
this.panel1.TabIndex = 2;
this.Controls.Add(this.panel1);
this.Controls.Add(this.scbMain);
this.Name = "CtrlScroll";
this.Size = new System.Drawing.Size(474, 300);
The scrolling:
public CtrlScroll() {
InitializeComponent();
scbMain.Scroll += ( sender, e ) => {
//Normally the if statement whouldn't be needed but the metro srollbar
//has a weird behaviour when the scroll value becomes max
if( scbMain.Value > panel1.Height - this.Height ) {
panel1.Top = -( panel1.Height - this.Height );
}
else {
panel1.Top = -scbMain.Value;
};
};
int maxVertical = panel1.Height;
// SmallChange is typically 1%.
int smallChangeVertical = Math.Max( (int)( maxVertical / 100 ), 1 );
// LargeChange is one page.
int largeChangeVertical = this.Height;
scbMain.Minimum = 0;
scbMain.Maximum = maxVertical;
scbMain.SmallChange = smallChangeVertical;
scbMain.LargeChange = largeChangeVertical;
}

Adding labels dynamically to a form: Labels not visible when trying to add more labels

I use this code to add some labels to a windows form in c#:
Label[] lbl = new Label[temp+1];
for (int i = 0; i <= temp; i++) {
lbl[i] = new Label();
lbl[i].Text = "" + i;
lbl[i].Location = new Point(30 + (i * unit), 380);
lbl[i].Visible = true;
this.Controls.Add(lbl[i]);
}
There is not a serious problem but my code works for temps less than 5 and for temps greater than 5 it shows only the first one.
What you think? where is the problem?
Make the labels automatically adjust their size to their content by setting their AutoSize property to true:
lbl[i] = new Label();
lbl[i].Text = "" + i;
lbl[i].Location = new Point(30 + (i * unit), 380);
lbl[i].Visible = true;
lbl[i].AutoSize = true;
this.Controls.Add(lbl[i]);
Without this, the labels have a fixed size. When this fixed size is greater than unit, the labels overlap and hide each other's text. With more labels to add, unit becomes smaller and then smaller than the default width of the labels when temp is ≥ 5.
Alternatively, you could set the labels' width to unit to make sure that they do not overlap.

Size adjustments for Panel control in windows forms

I have a Panel control on my winform which will display multiple panels inside that. For each inner panel I am setting its height. But some has less content to display some has more.
Panel hrvPanel = new Panel();
ArrayList hrvColl = pnlColl ; //Panel collection list gets from a Method
if(hrvColl.Count == 0)
return;
int splits = 0;
for(int p= hrvColl.Count-1;p>=0;p--)
{
Panel hrv = hrvColl[p] as Panel;
hrv.Height = 150;
hrvPanel.Controls.Add(hrv);
//Adding splliter
if(splits < hrvColl.Count - 1)
{
Splitter splitGrid = new Splitter();
splitGrid.Dock = DockStyle.Top;
hrvPanel.Controls.Add(splitGrid);
splits++;
}
}
hrvPanel.Dock = DockStyle.Top;
How to adjust the height of each inner panel based on its content size? I tried setting hrv.AutoSize to true,then I can see only the last panel And hrv.Dock = Top but the result is same.
If the outer Panel has Autosize = true you will be able to see all inner Panels. Promise.
If you don't, you have got some settings wrong. Make sure no unwanted settings of Dock and Anchor are used in the inner Panels.
It is also very simple to write code to find out the maximum of Top + Height over all inner Panels:
int max = 0;
foreach (Control ctl in panelOuter.Controls)
if (ctl.Top + ctl.Height > max) max = ctl.Top + ctl.Height;
panelOuter.Height = max + 3; // add the default margin!
This may be useful if you only want to set the Height and leave the Width as it is..other than that: The AutoSize property will do its job!
This is where WPF overcomes Winform, you probably can't do this automatically in Winforms. But you may have a work around like this-
Create an extended panel class that should know its preferred height
class ExPanel : Panel
{
public int PreferredHeight
{
get;
private set;
}
public ExPanel(int preferredHeight)
: base()
{
PreferredHeight = preferredHeight;
}
}
and then you can use this class as-
ExPanel hrvPanel = new ExPanel(150);
System.Collections.ArrayList hrvColl = pnlColl; //Panel collection list gets from a Method
if (hrvColl.Count == 0)
return;
int splits = 0;
for (int p = hrvColl.Count - 1; p >= 0; p--)
{
ExPanel hrv = hrvColl[p] as ExPanel;
hrv.Height = hrv.PreferredHeight;
hrvPanel.Controls.Add(hrv);
//Adding splliter
if (splits < hrvColl.Count - 1)
{
Splitter splitGrid = new Splitter();
splitGrid.Dock = DockStyle.Top;
hrvPanel.Controls.Add(splitGrid);
splits++;
}
}
hrvPanel.Dock = DockStyle.Top;
it's just an workaround to achieve your target, if you don't want to manage the height for your every panel.

how to set anchar for removing space between buttons

I have some buttons that are inside of a panel, like the picture(1)
Its a user control.
I want that when somebody use my usercontrol, when resize the panel, the button size and the space of between them will change.
actually I want to have picture (3) but picture(2) will happend...
I set the anchar of panel, to right, left, top, botton. how to fix the buttons like picture 3?!
1 - Set 'MaximumSize' and 'MinimumSize' for all buttons in your user control.Something like this :
btnSave.MaximumSize = new Size(80, 30);
btnSave.MinimumSize = new Size(60, 30);
btnEdit.MaximumSize = new Size(80, 30);
btnEdit.MinimumSize = new Size(60, 30);
.
.
.
Or set from properties window.
2 - Set ' Anchor ' property for all buttons to Left,Right
3 - Write following code for 'Resize' event in your user control
private void UserControl1_Resize(object sender, EventArgs e)
{
int lastLeft = 0 , lastWidth = 0 ;
foreach (Control ctrl in this.Controls)
{
ctrl.Left = lastLeft + lastWidth + 3;
lastLeft = ctrl.Left;
lastWidth = ctrl.Width;
}
}
Note : Don't forget that you must cut the buttons from panel and paste them into user control.you don't need to panel and you can delete it.
Hope this be useful.

Visibility and height problems when using wpf usercontrol in winforms project

I have two related problems that occur in the following situation.
I have a winforms window that contains some panels. In a few of these panels there are a number of (custom) wpf user-controls.
1
if i check .Visible on the elementhost it always returns true. even though I can see that its not visible.
2
if i check .Height it will always give me the same size. even though the control itself shows a variable number of things and changes size acordingly (through Visibility.collaps);
how can I get to the correct values?
edit: code added
Okey Now I'm officialy going crazy.
If I add a few messageboxes in my code to check when and in what order the above code gets executed. When I do this everything works! but as soon as I delete the messageboxes it reverses the effect. Instead of getting bigger when needed it gets smaller en vice versa....
wtf wpf!
private Size bereken_panel(Panel P)
{
Size Sz = new Size();
int tmp_H = 42;
foreach (Control SC in P.Controls)
{
if (SC is SplitContainer)
{
if (SC.Visible)
{
tmp_H += SC.Height;
}
}
else if (SC is System.Windows.Forms.Integration.ElementHost)
{
if ((SC as System.Windows.Forms.Integration.ElementHost).Child.Visibility == System.Windows.Visibility.Visible)
{
tmp_H += (int)(SC as System.Windows.Forms.Integration.ElementHost).Child.RenderSize.Height;
}
}
}
// tmp_H = 42 + n_showed * 25;
if (tmp_H < 65)
{
tmp_H = 65;
}
Sz.Height = tmp_H;
Sz.Width = 432;
return Sz;
}
so this is after some extra modification
to clarify where the TopLeft point is.
int p_x_links = panel1.Width / 2 - 436;
int p_x_rechts = panel1.Width / 2 + 4;
//links
p_contact_gegevens.Size = bereken_panel(p_contact_gegevens);
p_telnrs.Location = new Point(p_x_links, p_contact_gegevens.Size.Height + p_contact_gegevens.Location.Y + 8);
p_telnrs.Size = bereken_panel(p_telnrs);
p_bezoekadres.Location = new Point(p_x_links, p_telnrs.Size.Height + p_telnrs.Location.Y + 8);
p_bezoekadres.Size = bereken_panel(p_bezoekadres);
//rechts
p_administratie.Size = bereken_panel(p_administratie);
p_postadres.Location = new Point(p_x_rechts, p_administratie.Size.Height + p_administratie.Location.Y + 8);
p_postadres.Size = bereken_panel(p_postadres);
Most probabbly the control is overlapped by some other control. Visibility property in this case can be even True.
Try to use ActualWidth instead.
EDIT
Sorry, the example is on ActualWidth, but you are asking for Height. Concept is the same btw.

Categories