I am using this nice code which by the way if you are aware of any better way to accomplish this, I really appreciate letting us know .
so here is the Toolbar that can float :
http://en.csharp-online.net/Tool,_Menu,_and_Status_Strips%E2%80%94Floating_ToolStrips
good, but what if I only have 4 buttons on this toolbar, when I make it float it is still the same size as it was docked to the form before but I wish it could resize itself and just be as long as it needs to be to show its buttons on it .
m_floatForm.AutoSize = True
m_floatForm.AutoSizeMode = AutoSizeMode.GrowAndShrink
You can add up the widths of the individual toolstrip items and use that as the width of your form.
Replace this:
floatForm.ClientSize = this.Size;
with this:
//Adjust min value for your needs. It should account for the width of the
//toolstrip, borders, etc.
int minWidth = 20;
int newWidth = minWidth;
foreach (ToolStripItem item in this.Items)
{
newWidth += item.Size.Width;
}
floatForm.ClientSize = new Size(newWidth, this.Size.Height);
PreferredSize did the trick for me. I didn't expect to work on a ToolStip but it does, at least on .Net 4.5.
I still had to add a fixed number to account for a few pixels that I'm not sure where they are coming from.
this.Width = toolStrip.PreferredSize.Width + toolStrip.Margin.Horizontal + toolStrip.Parent.Margin.Horizontal + toolStrip.Parent.Padding.Horizontal+20;
Related
In a C# ListView with View=List, there is empty space at the bottom, reserved for a scrollbar. Weirdly, setting Scrollable=false will only increase the size of this unused space.
How can I get rid of this space or make sure it's used to display items?
Edit:
I'm having this issue in a Windows Form Application.
Edit 2: The issue seems to be coupled with the font size somehow. I need the font size to be 9 pt. With 11 pt this problem doesn't appear.
Edit 3: I also tried Item spacing in ListView where View=List but that didn't help either.
Edit 4: It happens under Win7 with the Win7 Theme. However, at least with Scrollable = false, it doesn't happen with the Classic Theme.
Still hoping for a more elegant solution, but for now, I found this workaround:
One can use a Panel to get rid of the extra space. I got the idea from TaW's answer to Add padding to last ListView item in WinForms
Remember, this worked for me, because I don't want or need a Scrollbar.
listView1.Scrollable = true;
int itemHeight = listView1.GetItemRect(0).Height;
int numItemsPerColumn = 10;
//One needs to add 21 to the height, because even if no Scrollbar
//is needed, that space will stay reserved.
listView1.Size = new Size(500, itemHeight * numItemsPerColumn + 21);
Panel P = new Panel();
P.BackColor = listView1.BackColor;
P.Location = listView1.Location;
//The height you actually want
P.Size = new Size(500, itemHeight * numItemsPerColumn + 4);
P.BorderStyle = listView1.BorderStyle;
listView1.BorderStyle = BorderStyle.None;
listView1.Parent = P;
listView1.Location = new Point(0, 0);
this.Controls.Add(P);
I have an auto-sized application user control in WPF (Height="Auto" Width="Auto"). When a bunch of elements inside it are resized, the windows stays the same rendered size. How do I force it to resize? I have tried this line Application.Current.MainWindow.SizeToContent = SizeToContent.WidthAndHeight; in the function that resizes the components inside the window. The compiler gives me an error that there is no object associated with this call. I have tried this line MainWindowBorder.Height = Double.NaN; to trick it to resize. No luck either.
Use SizeToContent in XAML
SizeToContent="WidthAndHeight"
https://msdn.microsoft.com/en-us/library/system.windows.window.sizetocontent%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396
If all the inside controls can be resized but the only one thing to resize is Window, How about this simple approach? Hope this helps..
int mycurrentscreenwidth = 1366;
int mycurrentwindowwidth = 1366;
var screen = System.Windows.Forms.Screen.PrimaryScreen.Bounds;
var screenwidth = screen.Width;
if (Convert.ToInt32(screenwidth) < 1366)
{
double calculate_scalefactor= Convert.ToInt32(screenwidth) / (double)mycurrentscreenwidth;
double newwidth_tobescaled = mycurrentwindowwidth * calculate_scalefactor;
this.Width = newwidth_tobescaled;
}
To obtain the window of your current user control, see:
Access parent window from User Control
Then use:
Window yourParentWindow = Window.GetWindow(userControl);
yourParentWindow.SizeToContent = SizeToContent.WidthAndHeight;
I'm working on a C# project using .NET 3.5 and Windows Forms. I need to design a decision step with multiple options that require a bit of explanatory text. For this, I want to have a set of RadioButtons to choose an option, followed by an additional Label each that contains the explanation.
I want to keep the label of the radio buttons and the label containing the explanatory text aligned - I've added red lines to the image to illustrate this. I could probably tweak some margins or other settings on the second label, but that would probably start to look weird as soon as the user chooses a different theme or changes some other settings. What is the canonical (and most robust) way to do this?
Your question boils down to two partial problems:
How large is the RadioButton (or the CheckBox when thinking ahead)..
How large is the gap between the glyph and the Text.
The first question is trivial:
Size s = RadioButtonRenderer.GetGlyphSize(graphics,
System.Windows.Forms.VisualStyles.RadioButtonState.CheckedNormal);
..using a suitable Graphics object. Note that I use the RadioButtonState CheckedNormal as I don't you want the Lables to align differently when the Buttons are checked or unchecked..
The second one is anything but trivial. The gap may or may not be constant and there is another gap to the left of the glyph! If I really wanted to get it right I guess I would write a routine to measure the text offset at startup:
public Form1()
{
InitializeComponent();
int gapRB = getXOffset(radioButton1);
int gapLB = getXOffset(label1);
label1.Left = radioButton1.Left + gapRB - gapLB;
}
Here is the measurement function. Note that is doesn't even use the Glyph measurement. Also note that it isn't enough to measure the text offset of the RadioButton. You also need to measure the offset of the Label!
int getXOffset(Control ctl)
{
int offset = -1;
string save = ctl.Text; Color saveC = ctl.ForeColor; Size saveSize = ctl.Size;
ContentAlignment saveCA = ContentAlignment.MiddleLeft;
if (ctl is Label)
{
saveCA = ((Label)ctl).TextAlign;
((Label)ctl).TextAlign = ContentAlignment.BottomLeft;
}
using (Bitmap bmp = new Bitmap(ctl.ClientSize.Width, ctl.ClientSize.Height))
using (Graphics G = ctl.CreateGraphics() )
{
ctl.Text = "_";
ctl.ForeColor = Color.Red;
ctl.DrawToBitmap(bmp, ctl.ClientRectangle);
int x = 0;
while (offset < 0 && x < bmp.Width - 1)
{
for (int y = bmp.Height-1; y > bmp.Height / 2; y--)
{
Color c = bmp.GetPixel(x, y);
if (c.R > 128 && c.G == 0) { offset = x; break; }
}
x++;
}
}
ctl.Text = save; ctl.ForeColor = saveC; ctl.Size = saveSize;
if (ctl is Label) { ((Label)ctl).TextAlign = saveCA; }
return offset;
}
Now the Texts do align pixel perfect..:
Note that I use two original controls from my form. Therefore much of the code is simply storing and restoring the properties I need to manipulate for the measurement; you can save a few lines by using two dummies.. Also note that I wrote the routine so that it can measure RadioButtons and Labels and probably CheckBoxes as well..
Is it worth it? You decide..!
PS: You could also owner-draw the RadioButton and the Label text in one.. this would have the interesting side-effect, that the whole text would be clickable..:
Here is a quick and dirty implementation of owner drawing a CheckBox: Prepare it by setting AutoSize = false and by adding the real text together with the extra text into the Tag, separated by a e.g. "§". Feel free to change this setup, maybe using the Label control..
I clear the Text to prevent it from drawing it and I decide on an offset. To measure it, you could use the GetGlyphSize from above.. Note how the DrawString method honors embedded '\n' characters.
The Tag contained this string:
A Rose is a Rose is a Rose..§A Rose is a rose is a rose is a rose is /
A rose is what Moses supposes his toes is / Couldn't be a lily or a
taffy daphi dilli / It's gotta be a rose cuz it rhymes with mose!
And I for the screenshot I actually used this line:
e.Graphics.DrawString(texts[1].Replace("/ ", "\n"), ...
Here is the Paint event:
private void checkBox1_Paint(object sender, PaintEventArgs e)
{
checkBox1.Text = "";
string[] texts = checkBox1.Tag.ToString().Split('§');
Font font1 = new Font(checkBox1.Font, FontStyle.Regular);
e.Graphics.DrawString(texts[0], checkBox1.Font, Brushes.Black, 25, 3);
if (texts.Length > 0)
{
SizeF s = e.Graphics.MeasureString(texts[1], checkBox1.Font, checkBox1.Width - 25);
checkBox1.Height = (int) s.Height + 30;
e.Graphics.DrawString(texts[1], font1, Brushes.Black,
new RectangleF(new PointF(25, 25), s));
}
}
The simplest out-of-the-box solution (it seems to me) would be to use 3 controls instead of 2: a radio button (with the text set to ""), a label (to go beside the radio button) and another label (to go below them). This would allow you easier configuration in designer, but (far more importantly) simpler run-time evaluation and adjustment, if necessary, to keep them in alignment should styles change.
I do understand that this takes away the benefit of clicking the label to select the radio button, but you could add that behavior in the label's Click event if you need it.
Alternatively, you could create a UserControl containing the text-free radio button and the label, and handle the behavior within that UserControl while exposing the label's location.
If you don't care about the radiobutton's text being bold, you could set it's label to a multiline string, and set CheckAlign to TopLeft:
radioButton2.CheckAlign = ContentAlignment.TopLeft;
radioButton2.Text = #"Radiobutton
Explanation text";
Don't know why I didn't think of this earlier, but the following approach seems to work:
Use a TableLayoutPanel with two columns that are set to adjust their width automatically.
Place all RadioButtons in the first column and set them to span both columns.
Place all Labels in the second column, setting all margins to 0.
Add a disabled, but visible (!) "spacer" RadioButton without text in an additional row at the end of the layout.
When displaying the form, convert the first column to a fixed size and hide the "spacer".
The key point seems to be that the "spacer" has to be visible initially - otherwise the column will get a size of 0.
This is my test form in the designer:
To change the layout, I used the following Load handler:
private void TestForm_Load(object sender, EventArgs e)
{
// find the column with the spacer and back up its width
int column = tableLayoutPanel.GetColumn(radioButtonSpacer);
int width = tableLayoutPanel.GetColumnWidths()[column];
// hide the spacer
radioButtonSpacer.Visible = false;
// set the column to the fixed width retrieved before
tableLayoutPanel.ColumnStyles[column].SizeType = SizeType.Absolute;
tableLayoutPanel.ColumnStyles[column].Width = width;
}
And this is the result at runtime:
You could add an invisible dummy label having the same text as the radiobutton. Then, get the length of that label and calculate the correct position of the explanation label.
labelDummy.Text = radioButton1.Text;
labelExplanation.Left = radioButton1.Right - labelDummy.Width;
However, this still appears to be some pixels off, even though I the label's margin to 0, maybe some additional tweaking can fix this. Here's a screenshot to show what I mean. The label's background is green to be able to see the extra margin.
I have one form which opens another form.
What I want to do is position the newly opened form right next (on the right side) to the already visible form.
So I need to position the new form to where the current form ends (correct me if wrong).
So I will need to do something like:
newform.Left = this.endposition.right;
The endposition property is something I just made up (pseudo code).
How to get the end position on the right side of the current form?
EDIT
I've tried several solutions but until now none of them worked.
I always get the same result:
I've tried the following codes:
newform.Left = this.Right + SystemInformation.BorderSize.Width;
newform.Left = this.Right + (SystemInformation.BorderSize.Width * 2);
newform.SetDesktopLocation(this.Location.X + this.Size.Width, this.Location.Y);
Eclyps19 suggested to just manually add some pixels to position the new form, although I'm not sure whether the border will be the same on every system.
This works for me:
Form1 nForm = new Form1();
nForm.Show();
nForm.SetDesktopLocation(this.Location.X + this.Size.Width, this.Location.Y);
Try
newform.Left = oldform.Right + SystemInformation.BorderSize.Width;
This should add the width (in pixels) of the border to the oldform.Right value. You can replace (or add to) SystemInformation.BorderSize.Width with any integer you'd like to fit your liking.
I Know this question is old, but for anyone coming here looking for an answer, you need to take into account the size of both form's borders. The border size will be different depending on the FormBorderStyle.
var newForm = new Form2();
newForm.Show();
var form1Border = (this.Width - this.ClientSize.Width) / 2;
var newFormBorder = (newForm.Width - newForm.ClientSize.Width) / 2;
newForm.Left = this.Left + this.Width - form1Border - newFormBorder;
Your code works fine, but you just have to put it AFTER your newForm.Show() method.
I have this code that adjusts the width of a comboBox drop-down:
private void comboBox_DropDown(object sender, EventArgs e)
{
ComboBox senderComboBox = (ComboBox)sender;
int width = senderComboBox.DropDownWidth;
Graphics g = senderComboBox.CreateGraphics();
Font font = senderComboBox.Font;
int vertScrollBarWidth =
(senderComboBox.Items.Count > senderComboBox.MaxDropDownItems)
? SystemInformation.VerticalScrollBarWidth : 0;
int newWidth;
foreach (string s in ((ComboBox)sender).Items)
{
newWidth = (int)g.MeasureString(s, font).Width
+ vertScrollBarWidth;
if (width < newWidth)
{
width = newWidth;
}
}
senderComboBox.DropDownWidth = width;
}
It works great, except it expands the width of the drop-down to the right, whereas I would prefer it to expand to the left because the comboBox is located on the right side of my form. Any thoughts or suggestions you may have would be appreciated. Thanks.
Ok, so .Anchor didn't work like I expected it to, so here's a completely new answer which does work, but I feel is kind of a hack, (but maybe it's a perfectly reasonable way to manage it):
int x = 10;
comboBox1.Location = new Point(comboBox1.Location.X - x, comboBox1.Location.Y);
comboBox1.Width += x;
This code pulls it back along the x-axis by 10 pixels, and then expands ComboBox1 by 10 pixels.
This works very smoothly for me. Does this work for you?
I wrote up an article on CodeProject on how to hack the combo-box to give it a scroll bar to scroll horizontally. See here for the article.
You might want to look at placing the control within a container. For instance, create a FlowLayoutPanel with its FlowDirection property to RightToLeft. Place the ComboBox within the new panel. One benefit of this method is you may change the dimensions by any means and the control/container will behave as expected.
After much searching, it appears that this is actually along-standing problem that Microsoft has yet to address (big surprise). I've decided to re-arrange my layout to better-accomodate this feature-lack when I get the time, but for now, I'm just going to live with it. Thanks, everyone, for your input.