I have trying to use that about bopx in my WPF application http://www.nuget.org/packages/AboutBox/
but i cant figure out how to resize it and how to make it not dragable. I tried that but no way:
About about = new About();
about.Window.Width = 120;
about.Window.Height = 130;
about.Window.MaxWidth = 120;
about.Window.MaxHeight = 130;
about.Window.MinWidth = 120;
about.Window.MinHeight = 130;
about.Window.ResizeMode = ResizeMode.NoResize;
about.Window.WindowStyle = WindowStyle.ToolWindow;
about.Window.WindowState = WindowState.Minimized;
about.Window.AllowDrop = false;
about.Show();
May be some one may help.
Also I would like to display close or OK button to close the window, and want to disable closing window when focus is loosing.
UPDATE:
I ended up by using http://wpfmbx.codeplex.com/ it is exactly what i need
I have not tried that About box but following should be the correct order for heights:
About about = new About();
about.Window.MinWidth = 120;
about.Window.MinHeight = 130;
about.Window.MaxWidth = 120;
about.Window.MaxHeight = 130;
about.Window.Width = 120;
about.Window.Height = 130;
MinWidth/MinHeight takes precedence then comes MaxWidth/MaxHeight and Width/Height. I am not 100 % sure that it is the cause of your problem, just give it a try.
To be able to make it drag-able manually, then you just need to call DragMove(), on MouseDown or some similar event.
Related
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.
I set this to make the scrollbar invisble to my tablelayoutpanel:
tableLayoutPanel1.AutoScroll = false;
tableLayoutPanel1.HorizontalScroll.Visible = false;
tableLayoutPanel1.HorizontalScroll.Maximum = 0;
tableLayoutPanel1.VerticalScroll.Maximum = 0;
tableLayoutPanel1.VerticalScroll.Visible = false;
tableLayoutPanel1.AutoScroll = true;
How Can I set to button click scrolling to right and left?
I tried this:
int change = tableLayoutPanel1.HorizontalScroll.Value + tableLayoutPanel1.HorizontalScroll.SmallChange * 40; tableLayoutPanel1.AutoScrollPosition = new Point(change, 0);
but it's scrolled only once time.
Do it this way instead:
int change = tableLayoutPanel1.HorizontalScroll.SmallChange * 40;
tableLayoutPanel1.AutoScrollPosition = new Point(Math.Abs(tableLayoutPanel1.AutoScrollPosition.X) + change , 0);
We need Math.Abs() since the values returned by AutoScrollPosition are negative.
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;
}
The problem
I'm dynamically adding Buttons to the WinForm. As I do so, I'm repositioning existing Buttons to prevent overlap. The AutoSize property is being used to automatically set Width.
For longer text (that pushes Buttons beyond their default Width), the below code doesn't work.
For example:
b.Width is 75 before AutoSize is set
b.Width is 75 after AutoSize is set
When shifting other Buttons, it shifts them by b.Width + buffer = 83
However after addButton()completes, the AutoSize kicks in and sets the width to 150, overlapping the next Button which is only 83 pixels away instead of 158.
AutoSize appears to change the size of the control too late for it to be of use. How can I make it happen immediately?
Attempt 1 - Code
public void addButton(string text)
{
const int buffer = 8;
//Construct new button
Button b = new Button();
b.Text = text;
b.AutoSize = true;
b.Location = new Point(0, 0);
//Shift over all other buttons to prevent overlap
//b.Width is incorrect below, because b.AutoSize hasn't taken effect
for (int i = 0; i < Controls.Count; i++)
if (Controls[i] is Button)
Controls[i].Location = new Point(Controls[i].Location.X + b.Width + buffer, Controls[i].Location.Y);
Controls.add(b);
}
Attempt 2
Searched Google and StackOverflow for the following:
c# autosize immediately
c# autosize fast
c# autosize not working
Attempt 3
Asking here.
Last Resort
If nothing else works, a timer could be set to reposition Buttons on each tick. However this is very sloppy design, and doesn't aid in learning the intricacies of AutoSize. I'd like to avoid this workaround if possible.
The AutoSize and AutoSizeMode mode are applied only when the control is parented to the another control or form.
So invoke first
Controls.Add(b);
Now the b.Size will the adjusted accordingly and can be used in the calculations.
Alternatively, instead of Size property you can use the GetPreferredSize method to get the correct size without actually applying AutoSize and use it inside the calculations:
var bSize = b.GetPreferredSize(Size.Empty);
//Shift over all other buttons to prevent overlap
//b.Width is incorrect below, because b.AutoSize hasn't taken effect
for (int i = 0; i < Controls.Count; i++)
if (Controls[i] is Button)
Controls[i].Location = new Point(Controls[i].Location.X + bSize.Width + buffer, Controls[i].Location.Y);
The FlowLayoutPanel control does this work for you.
Place one on your form and try adding buttons in the following manner:
Button b = new Button();
b.AutoSize = true;
b.Text = text;
flowLayoutPanel1.SuspendLayout();
flowLayoutPanel1.Controls.Add(b);
flowLayoutPanel1.Controls.SetChildIndex(b, 0);
flowLayoutPanel1.ResumeLayout();
You can subscribe to the Resize event of the last button added. This will allow you to accurately change the locations of all of the buttons because now all of the buttons have been AutoSized.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
var button1 = NewButton(0);
button1.Location = new Point(10, 10);
var button2 = NewButton(1);
button2.Location = new Point(button1.Right, 10);
var button3 = NewButton(2);
button3.Location = new Point(button2.Right, 10);
button3.Resize += (s, e) =>
{
button2.Location = new Point(button1.Right, 10);
button3.Location = new Point(button2.Right, 10);
};
Controls.Add(button1);
Controls.Add(button2);
Controls.Add(button3);
}
private Button NewButton(int index)
{
return new Button()
{
Text = "ButtonButtonButton" + index.ToString(),
AutoSize = true
};
}
}
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.