How to scroll in TabPages/TabControl - c#

I've tabcontrol with 3 pages. Within the tabpages are placed listviews. The listviews can be bigger than the tabpage itself.
I wanna add scrollbars on the tabpages
I tried to solve this with the following source:
lvwAlbums.Parent = pctlDatabeheer.TabPages[1];
lvwAlbums.Left = 0;
lvwAlbums.Top = 0;
lvwAlbums.Width = pctlDatabeheer.TabPages[1].Width - 35;
lvwAlbums.Height = 1000;// pctlDatabeheer.TabPages[1].Height;
lvwAlbums.SmallImageList = iltListView;
lvwAlbums.FullRowSelect = true;
lvwAlbums.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top;
foreach (TabPage _Page in pctlDatabeheer.TabPages)
{
_Page.AutoScroll = true;
_Page.AutoScrollMargin = new System.Drawing.Size(20, 20);
_Page.AutoScrollMinSize = new System.Drawing.Size(_Page.Width, _Page.Height);
}
But the scroll are not shown. What do I wrong?
Can anybody help me?
Thank yopu for your help.

I created a new Visual Studio WinForms project. Kept the form designer completely empty and used your code:
public Form1()
{
InitializeComponent();
// Make TabControl
TabControl tabControl1 = new TabControl();
tabControl1.TabPages.Add(new TabPage());
tabControl1.TabPages.Add(new TabPage());
tabControl1.Dock = DockStyle.Fill;
this.Controls.Add(tabControl1);
// Make long ListView and add to first tab
ListView listView1 = new ListView();
listView1.Location = new Point(0, 0);
listView1.Height = 1000;
tabControl1.TabPages[0].Controls.Add(listView1);
// Your code
foreach (TabPage _Page in tabControl1.TabPages)
{
_Page.AutoScroll = true;
_Page.AutoScrollMargin = new System.Drawing.Size(20, 20);
_Page.AutoScrollMinSize = new System.Drawing.Size(_Page.Width, _Page.Height);
}
}
Works perfectly fine. I suspect you have something else wrong but I can't see that or troubleshoot it without seeing your code.
EDIT: Now that you posted some more code, your issue is with your list box:
lvwAlbums.Parent = pctlDatabeheer.TabPages[1];
lvwAlbums.Left = 0;
lvwAlbums.Top = 0;
lvwAlbums.Width = pctlDatabeheer.TabPages[1].Width - 35;
lvwAlbums.Height = 1000;
lvwAlbums.SmallImageList = iltListView;
lvwAlbums.FullRowSelect = true;
// Here is the issue!
// Do not anchor to the bottom or scrolling won't work
lvwAlbums.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top;
Don't anchor the control to the bottom. That is causing you the issue. You cannot anchor to the bottom and then scroll. The other anchors are fine.

Related

Make a button distance itself dynamically from another

I am adding a new button in a Form in which there are already 2 existing ones. The problem occurs when btnCancel's content changes to a longer string, which makes the button auto-resize - hence, overlapping the button that I have added.
The Proxy Settings is the button that I added. If I change Don't sign in to a much longer string, then the middle button would overlap mine.
The code for the buttons is below:
//
// btnLogin
//
this.btnLogin.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnLogin.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;
this.btnLogin.Location = new System.Drawing.Point(340, 50);
this.btnLogin.Margin = new System.Windows.Forms.Padding(2);
this.btnLogin.Name = "btnLogin";
this.btnLogin.Size = new System.Drawing.Size(82, 24);
this.btnLogin.TabIndex = 0;
this.btnLogin.Text = "Sign in...";
this.btnLogin.UseVisualStyleBackColor = true;
this.btnLogin.Click += new System.EventHandler(this.btnLogin_Click);
//
// btnCancel
//
this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.btnCancel.Location = new System.Drawing.Point(239, 50);
this.btnCancel.Margin = new System.Windows.Forms.Padding(2);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(94, 24);
this.btnCancel.TabIndex = 1;
this.btnCancel.Text = "Don\'t sign in";
this.btnCancel.UseVisualStyleBackColor = true;
//
// btnProxySettings
//
this.btnProxySettings.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnProxySettings.Location = new System.Drawing.Point(138, 50);
this.btnProxySettings.Margin = new System.Windows.Forms.Padding(2);
this.btnProxySettings.Name = "btnProxySettings";
this.btnProxySettings.Size = new System.Drawing.Size(92, 24);
this.btnProxySettings.TabIndex = 2;
this.btnProxySettings.Text = "Proxy Settings";
this.btnProxySettings.UseVisualStyleBackColor = true;
this.btnProxySettings.Click += new System.EventHandler(this.btnProxySettings_Click);
How can I make the latter button distance itself dynamically?
Edit as I noticed that my post got downvoted. I have tried several "calculations" using the data within btnCancel like location, size, width, etc. but I could not figure out a "rule" so to say. Or maybe there's even a method that I could not find which does everything "magically"? So it's not like I'm asking for you to do my homework or anything, but I found it useless for the current situation to showcase my poor attempts.
Put the buttons in a flowLayoutPanel with a RightToLeft FlowDirection. This should guarantee proper separation without any need to manually calculate any positions. Whenever you work with auto-scaling controls it is usually a good idea to use some kind of panel with an automatic layout.

Manage a ControlCollection - display a new element at the bottom

I need to add a simple at the bottom of an existing view. It is composed of nested panels in a code which I know is not proper. But what I want given my available time is (simple as it sounds) to add my link below what is existing.
In a few words, there is a ControlCollection object being displayed (this.Controls), and I can't locate an element (LinkLabel or TableLayoutPanel) below the other elements.
Here is the minimal existing code :
private void SetAppearance()
{
pnlTitle = new Panel();
pnlTitle.x = ...
this.Controls.Add(pnlTitle);
lblTitle = new Label();
lblTitle.x = ...
pnlTitle.Controls.Add(lblTitle);
tlpnlCountryOfOrigin = new TableLayoutPanel();
tlpnlCountryOfOrigin.x = ...
pnlTitle.Controls.Add(tlpnlCountryOfOrigin);
CountryOfOrigin = new Label();
CountryOfOrigin.x = ...
tlpnlCountryOfOrigin.Controls.Add(CountryOfOrigin, 0, 0);
cbbCountryOrigin = new ComboBoxWithBorders();
cbbCountryOrigin.x = ...
tlpnlCountryOfOrigin.Controls.Add(cbbCountryOrigin, 1, 0);
pnlSupportInfo = new TableLayoutPanel();
pnlSupportInfo.x = ...
this.Controls.Add(pnlSupportInfo);
}
And I am just basically wanting to add my LinkLabel at the bottom of that, with that :
lnkSendLogs = new LinkLabel
{
Font = new Font(ArialBold12px, FontStyle.Regular | FontStyle.Underline),
AutoSize = true,
LinkColor = InfomaxConstants.Colors.Red,
Margin = new Padding(0),
Text = LabelManager.GetLabel("TEXTTOGETLABEL")
};
this.Controls.Add(lnkSendLogs);
Or even with a nested TableLayoutPanel (which I know is not a good practice) :
tlpnlSendLogs = new TableLayoutPanel();
tlpnlSendLogs.ColumnCount = 2;
tlpnlSendLogs.ColumnStyles.Clear();
tlpnlSendLogs.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 100));
tlpnlSendLogs.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
lnkSendLogs = new LinkLabel
{
Font = new Font(ArialBold12px, FontStyle.Regular | FontStyle.Underline),
AutoSize = true,
LinkColor = InfomaxConstants.Colors.Red,
Margin = new Padding(0),
Text = LabelManager.GetLabel("TEXTTOGETLABEL")
};
lnkSendLogs.Dock = DockStyle.Fill;
tlpnlSendLogs.Controls.Add(lnkSendLogs, 0, 0);
this.Controls.Add(tlpnlSendLogs);
But the link is always appearing behind other elements, instead of below them.
The question is thus the very basic : How to add a simple LinkLabel appearing at the bottom of a view containing a few elements like Panels and TableLayoutPanels ?
The first problem was that the controls had no location settings, which makes room for random and unwanted things.
Two things to have in mind for the ControlCollection elements:
Locate them
Order them
The thing to know is that the Controls of a ControlCollection are ordered based on their index, AND the one of bigger index will be the one the most at the border of the container (whatever the order in which the children elements anchor are being defined) (https://stackoverflow.com/a/7685041/6617804)
A solution is
1-To set the position of all the ControlCollection elements to the top of their container
pnlTitle.Dock = DockStyle.Top;
pnlSupportInfo.Dock = DockStyle.Top;
tlpnlSendLogs.Dock = DockStyle.Top;
Or the exact same :
pnlTitle.Anchor = (AnchorStyles.Left | AnchorStyles.Top);
pnlSupportInfo.Anchor = (AnchorStyles.Left | AnchorStyles.Top);
tlpnlSendLogs.Anchor = (AnchorStyles.Left | AnchorStyles.Top);
2.1-To arrange the child in the opposite order If we need to (in my case where we want to display them in the opposite order)
this.Controls.SetChildIndex(pnlTitle, 2);
this.Controls.SetChildIndex(pnlSupportInfo, 1);
this.Controls.SetChildIndex(tlpnlSendLogs, 0);
2.2-OR to add them directly in the order they need to be for the display :
this.Controls.Add(tlpnlSendLogs);
this.Controls.Add(pnlSupportInfo);
this.Controls.Add(pnlTitle);
Instead of :
this.Controls.Add(pnlTitle);
this.Controls.Add(pnlSupportInfo);
this.Controls.Add(tlpnlSendLogs);

Setting anchor for dynamic created controls

I have winform on which are dynamically created 52 radio buttons.
This is method for creating them:
private void CreateRadioButton()
{
int rbCount = 52;
int numberOfColumns = 23;
radioButtons = new RadioButton[rbCount];
int y = 520;
for (int i = 0; i < rbCount; i++)
{
radioButtons[i] = new RadioButton();
radioButtons[i].Text = Convert.ToString(i + 1);
if (i % numberOfColumns == 0)
y += 20;
var x = 11 + i % numberOfColumns * 50;
radioButtons[i].Location = new Point(x, y);
radioButtons[i].Size = new Size(40, 15);
//radioButtons[i].Anchor = AnchorStyles.Left;
//radioButtons[i].Anchor = AnchorStyles.Bottom;
radioButtons[i].Font = new Font(radioButtons[i].Font.FontFamily, 8, FontStyle.Bold);
radioButtons[i].UseVisualStyleBackColor = true;
radioButtons[i].Click += new EventHandler(rbtns_click);
xtraTab.Controls.Add(radioButtons[i]);
}
}
There is problem when form is maximized. Radio buttons disappear.
If I set
radioButtons[i].Anchor = AnchorStyles.Left;
radioButtons[i].Anchor = AnchorStyles.Bottom;
The radio buttons are overlayed.
What can I do to keep their position on the same place if form is resized?
these two lines
radioButtons[i].Anchor = AnchorStyles.Left;
radioButtons[i].Anchor = AnchorStyles.Bottom;
mean that Anchor value AnchorStyles.Left will be replaced by AnchorStyles.Bottom
AnchorStyles has Flags attribute set, enum values can be combined:
radioButtons[i].Anchor = AnchorStyles.Left | AnchorStyles.Bottom;
if set via Designer, in "Windows Form Designer generated code" it looks like this:
this.radioButton1.Anchor = ((System.Windows.Forms.AnchorStyles)
((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));

AxWindowsMediaPlayer control location/size

I have a AxWindowsMediaPlayer control on my WinForm.
Everything works so far. But I can't resize or move the control.
I initialize the control like this:
mediaPlayer = new AxWMPLib.AxWindowsMediaPlayer();
mediaPlayer.CreateControl();
mediaPlayer.enableContextMenu = false;
((System.ComponentModel.ISupportInitialize)(mediaPlayer)).BeginInit();
mediaPlayer.Name = "wmPlayer";
mediaPlayer.Enabled = true;
mediaPlayer.Dock = System.Windows.Forms.DockStyle.Fill;
mediaPlayer.Size = this.Size;
this.Controls.Add(mediaPlayer);
((System.ComponentModel.ISupportInitialize)(mediaPlayer)).EndInit();
mediaPlayer.uiMode = "none";
mediaPlayer.URL = fileName;
mediaPlayer.settings.setMode("loop", true);
mediaPlayer.Ctlcontrols.play();
But the size ist always the same. How can I set the Size or the Bounds of this Controls?
Thanks for help
It is better do this in designer, rather than code.
In your code, you set the size of the player control as large as the form.
//occupies all the form's available space
mediaPlayer.Dock = System.Windows.Forms.DockStyle.Fill;
//again, the player is the same size as form
mediaPlayer.Size = this.Size;
In order to set the bound of the player control within the form, you can set the its AnchorStyle- anchoring the control to the edges of the form- and set the control's Location and Size properties.
mediaPlayer.Location = new Point(50, 50);
mediaPlayer.Size = new Size(this.ClientSize.Width - 100, this.ClientSize.Height - 100);
mediaPlayer.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom;
For anyone who wants to zoom in on AxWindowsMediaPlayer
axWindowsMediaPlayer1.stretchToFit = true;
axWindowsMediaPlayer1.Width *= 2;
axWindowsMediaPlayer1.Height *= 2;

C# Add Controls To Panel In a Loop

I wish to add a button for every line in a file to a panel.
My code so far is:
StreamReader menu = new StreamReader("menu.prefs");
int repetition = 0;
while(!menu.EndOfStream)
{
Button dynamicbutton = new Button();
dynamicbutton.Click += new System.EventHandler(menuItem_Click);
dynamicbutton.Text = menu.ReadLine();
dynamicbutton.Visible = true;
dynamicbutton.Location = new Point(4+repetition*307, 4);
dynamicbutton.Height = 44;
dynamicbutton.Width = 203;
dynamicbutton.BackColor = Color.FromArgb(40,40,40);
dynamicbutton.ForeColor = Color.White;
dynamicbutton.Font = new Font("Lucida Console", 16);
dynamicbutton.Show();
menuPanel.Controls.Add(dynamicbutton);
repetition++;
MessageBox.Show(dynamicbutton.Location.ToString());
}
menu.Close();
The problem is that only the first control gets created.
The code looks fine but there could be a following situations.
1.You might have only one entry in the file, so you are experiencing only One Button added to the panel.
2.Your panel width is smaller than the sum of all the dynamic buttons width.
I suspect no 2 is the main reason that is causing problem.
So, I recommend that you use FlowLayoutPanel. To add a dynamic content as it automatically layout all the child controls.
Each time it is generating the same name for dynamic controls. That's the reason why it is showing only the last one. It simply overwrites the previous control each time.
int x = 4;
int y = 4;
foreach(PhysicianData pd in listPhysicians)
{
x = 4;
y = panPhysicians.Controls.Count * 30;
RadioButton rb = new RadioButton();
rb.CheckedChanged += new System.EventHandler(rbPhysician_CheckedChanged);
rb.Text = pd.name;
rb.Visible = true;
rb.Location = new Point(x, y);
rb.Height = 40;
rb.Width = 200;
rb.BackColor = SystemColors.Control;
rb.ForeColor = Color.Black;
rb.Font = new Font("Microsoft Sans Serif", 10);
rb.Show();
rb.Name = "rb" + panPhysicians.Controls.Count;
panPhysicians.Controls.Add(rb);
}
Try this code
StreamReader menu = new StreamReader("menu.prefs");
var str = menu.ReadToEnd();
var items = str.Split(new string[] {"\r\n" } , StringSplitOptions.RemoveEmptyEntries);
foreach (var item in items)
{
Button dynamicbutton = new Button();
dynamicbutton.Click += new System.EventHandler(menuItem_Click);
dynamicbutton.Text = item;
dynamicbutton.Visible = true;
dynamicbutton.Location = new Point(4+repetition*307, 4);
dynamicbutton.Height = 44;
dynamicbutton.Width = 203;
dynamicbutton.BackColor = Color.FromArgb(40,40,40);
dynamicbutton.ForeColor = Color.White;
dynamicbutton.Font = new Font("Lucida Console", 16);
dynamicbutton.Show();
menuPanel.Controls.Add(dynamicbutton);
repetition++;
}
The problem with Panel and similar controls other than the FlowLayoutPanel is when you create a control and a second one, the second is created at the same position if you are not changing it's location dynamically or setting it according to the other already added controls. Your control is there, it's in the back of the first control.
A flowLayoutPanel is better as it will add the controls next to each other as you add them while compromising more finer control at their positioning.
I also have similar problems with panels. For what you are doing it could be useful to just add strings to a listbox rather than using labels and a panel. That should be simpler.

Categories